/* ==========================================================================
   base.css - design tokens, reset, typography, layout primitives
   --------------------------------------------------------------------------
   THIS IS THE FILE TO EDIT for brand colours, fonts and spacing. Every other
   stylesheet builds on the custom properties declared here.

   Token names are semantic (--ink, --surface, --brand) rather than positional,
   so changing a value changes it everywhere it means the same thing.
   ========================================================================== */

:root {
  /* --- colour ------------------------------------------------------------ */
  --ink:            #121212;  /* darkest surface: dark page sections        */
  --ink-soft:       #171717;  /* footer                                     */
  --ink-raised:     #1E1E1E;  /* buttons, accordion panels, upload box      */
  --muted:          #86868B;  /* body text on light, inactive nav on dark   */
  --surface:        #E9E9EB;  /* light card / tile background               */
  --surface-alt:    #FAFAFC;  /* nav hover on dark                          */
  --line:           #D0D0D0;  /* hairlines, secondary button fill           */
  --paper:          #FFFFFF;

  --on-dark:        #FFFFFF;
  --on-dark-dim:    rgba(255, 255, 255, 0.55);
  --on-light:       #1E1E1E;

  /* --- type -------------------------------------------------------------- */
  --font: "Roboto", system-ui, -apple-system, "Segoe UI", sans-serif;

  --text-sm:    14px;
  --text-base:  16px;
  --text-lg:    18px;
  --text-xl:    24px;
  --text-2xl:   32px;
  --text-price: 50px;

  --weight-normal: 400;
  --weight-medium: 500;
  --weight-bold:   600;

  /* --- layout ------------------------------------------------------------ */
  --container: 1120px;
  --gutter: 20px;

  --space-1:  5px;
  --space-2: 10px;
  --space-3: 20px;
  --space-4: 40px;
  --space-5: 50px;
  --space-6: 100px;

  --radius:    10px;
  --radius-sm:  5px;

  --shadow-hover: 0 0 10px 4px rgba(0, 0, 0, 0.1);
  --transition: 0.3s ease;

  /* Height of the fixed header. The hero sits underneath it, so this is the
     offset anchored scrolling has to clear. */
  --header-height: 120px;
  --header-height-stuck: 70px;
}

/* --------------------------------------------------------------------------
   reset
   -------------------------------------------------------------------------- */

*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

/**
 * Undoes one casualty of the reset above. The UA stylesheet centres a modal
 * <dialog> with `position: fixed; inset: 0; margin: auto` - `margin: auto` is
 * the entire centring mechanism. Zeroing it leaves the dialog pinned to the
 * top-left corner of that inset box. Restore it here rather than positioning
 * each dialog by hand, so any dialog added later is centred by default.
 */
dialog {
  margin: auto;
}

html {
  -webkit-text-size-adjust: 100%;
}

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
    /* Anchors must clear the fixed header. */
    scroll-padding-top: var(--header-height-stuck);
  }
}

body {
  font-family: var(--font);
  font-size: var(--text-base);
  font-weight: var(--weight-normal);
  line-height: 1.6;
  color: var(--muted);
  background: var(--paper);
  /* The header is fixed and the hero slides under it. */
  overflow-x: hidden;
}

img,
picture,
video,
svg {
  display: block;
  max-width: 100%;
  height: auto;
}

button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
}

button {
  cursor: pointer;
  background: none;
  border: none;
}

a {
  color: inherit;
  text-decoration: none;
}

ul,
ol {
  list-style: none;
}

h1, h2, h3, h4, h5, h6 {
  font-weight: var(--weight-bold);
  line-height: 1.2;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

/* --------------------------------------------------------------------------
   layout primitives
   -------------------------------------------------------------------------- */

/** Horizontal rhythm. Every full-width band wraps its content in one. */
.wrap {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/** A full-bleed band. `.band--dark` paints the near-black page sections. */
.band {
  width: 100%;
}

.band--dark {
  background: var(--ink);
}

/* --------------------------------------------------------------------------
   typography helpers
   -------------------------------------------------------------------------- */

.title {
  font-size: var(--text-2xl);
  font-weight: var(--weight-medium);
  color: var(--on-dark);
}

.prose p + p {
  margin-top: 1em;
}

/**
 * Inline links in body copy. :not(.btn) keeps these rules off buttons that
 * happen to sit inside prose - a .btn must look identical wherever it is used,
 * and four of the six on the site (the hero pair, the 404 pair) are outside
 * .prose and were never picking these up.
 *
 * The exclusion is load-bearing on the hover rule, not just cosmetic:
 * `.prose a:hover` is specificity (0,2,1) and beats `.btn:hover` at (0,2,0),
 * so it overrode the button's own `color: var(--ink)` with `var(--line)` on
 * top of the `background: var(--line)` that .btn:hover sets - #D0D0D0 text on
 * a #D0D0D0 fill, i.e. the label disappeared on hover.
 */
.prose a:not(.btn) {
  text-decoration: underline;
  text-underline-offset: 2px;
}

.prose a:not(.btn):hover,
.prose a:not(.btn):focus-visible {
  color: var(--line);
}

@media (max-width: 767px) {
  .title {
    font-size: var(--text-xl);
  }
}

/* --------------------------------------------------------------------------
   buttons
   -------------------------------------------------------------------------- */

.btn {
  display: inline-block;
  padding: 12px 24px;
  border-radius: 3px;
  font-size: var(--text-base);
  font-weight: var(--weight-medium);
  line-height: 1;
  text-align: center;
  background: var(--ink-raised);
  color: var(--on-dark);
  transition: background var(--transition), color var(--transition);
}

.btn:hover,
.btn:focus-visible {
  background: var(--line);
  color: var(--ink);
}

/** Solid light button - the hero's "Subscribe". */
.btn--light {
  background: var(--line);
  color: var(--on-light);
}

.btn--light:hover,
.btn--light:focus-visible {
  background: var(--paper);
  color: var(--on-light);
}

/** Translucent button over imagery - the hero's "Let's talk". */
.btn--ghost {
  background: rgba(255, 255, 255, 0.55);
  color: var(--on-light);
}

.btn--ghost:hover,
.btn--ghost:focus-visible {
  background: var(--paper);
  color: var(--on-light);
}

/* --------------------------------------------------------------------------
   accessibility
   -------------------------------------------------------------------------- */

.skip-link {
  position: absolute;
  top: -100px;
  left: var(--gutter);
  z-index: 1000;
  padding: 12px 20px;
  border-radius: 0 0 var(--radius-sm) var(--radius-sm);
  background: var(--paper);
  color: var(--ink);
  font-weight: var(--weight-medium);
  transition: top 0.2s ease;
}

.skip-link:focus {
  top: 0;
}

/** Visually hidden but read by screen readers. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--line);
  outline-offset: 2px;
}

/* --------------------------------------------------------------------------
   scroll reveal
   --------------------------------------------------------------------------
   Blocks fade and rise as they scroll into view. initReveal() in main.js picks
   the targets by selector and adds .reveal itself, then .is-revealed once the
   element crosses the viewport.

   The starting class is applied BY SCRIPT and never written into the HTML.
   That is deliberate: with JavaScript off, blocked, or thrown before this
   runs, no element ever carries `opacity: 0`, so the page cannot end up
   permanently blank. main.js also skips the whole thing under
   prefers-reduced-motion, which is why there is no override for it here.
   -------------------------------------------------------------------------- */

.reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.7s ease, transform 0.7s ease;
}

.reveal.is-revealed {
  opacity: 1;
  transform: none;
}

/* --------------------------------------------------------------------------
   shared components used on more than one page
   -------------------------------------------------------------------------- */

/**
 * Tile grid - the icon-link tiles on home / careers / enquire.
 * Column count is set per page; the tile styling is shared.
 */
.tiles {
  display: grid;
  gap: var(--space-3);
  margin-block: var(--space-6);
}

.tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 150px;
  padding: var(--space-3);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--muted);
  text-align: center;
  transition: box-shadow var(--transition), color var(--transition);
}

.tile:hover,
.tile:focus-visible {
  box-shadow: var(--shadow-hover);
  color: var(--ink);
}

.tile svg {
  width: 30px;
  height: 30px;
  fill: currentColor;
}

.tile__label {
  font-size: var(--text-lg);
  font-weight: var(--weight-normal);
}

@media (max-width: 1024px) {
  .tiles {
    margin-block: var(--space-5);
  }
}

/**
 * Hero band with a darkened photographic background. Used by every page
 * except home (which uses video instead - see home.css).
 */
/**
 * No top padding: the fixed header floats over the hero rather than sitting
 * above it, exactly as the export's -120px header margin arranged. Adding
 * padding here makes every hero taller than the 40vh it should be.
 */
.hero {
  display: flex;
  align-items: flex-end;
  min-height: 40vh;
  position: relative;
  isolation: isolate;
}

/**
 * The photograph is passed in from the page markup as --hero-image, so the
 * image URL stays with the page it belongs to rather than being scattered
 * through the stylesheets.
 */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image: var(--hero-image);
  background-position: center;
  background-size: cover;
  filter: brightness(30%) saturate(0%);
}

/* 50px below the title only - the export set margin, not symmetric padding. */
.hero__title {
  margin-bottom: var(--space-5);
  font-size: var(--text-2xl);
  font-weight: var(--weight-bold);
  color: var(--on-dark);
}

@media (min-width: 1201px) {
  /* Parallax on desktop only - fixed attachment is janky on touch devices. */
  .hero::before {
    background-attachment: fixed;
  }
}

/** "Get in Touch" band that closes every page. */
.contact-band {
  padding-bottom: var(--space-6);
  background: var(--ink);
}

.contact-band__title {
  padding-top: var(--space-5);
  padding-bottom: var(--space-5);
  font-size: var(--text-2xl);
  font-weight: var(--weight-bold);
  color: var(--on-dark);
  text-align: center;
}

@media (max-width: 767px) {
  .contact-band {
    padding-bottom: var(--space-5);
  }

  .contact-band__title {
    padding-top: var(--space-4);
    padding-bottom: var(--space-4);
  }
}
