/* varahi-responsive.css — one shared responsive layer for every page.
 *
 * Why !important throughout: these pages came out of the design canvas as
 * inline styles (438 of them on index.html alone). An inline style beats any
 * stylesheet rule regardless of specificity, so overriding one from here needs
 * !important. Nothing else in the project uses it — if you see it, it is this
 * file correcting a hard-coded desktop value for a smaller screen.
 *
 * Breakpoints, and what each is actually for:
 *   1080  large tablet landscape — trim the 56px gutters
 *    900  tablet portrait        — two-column grids that no longer fit
 *    760  large phone / nav      — single column, nav collapses to a toggle
 *    560  phone                  — every grid to one column, heroes shrink
 *    380  small phone            — tighten gutters and display type further
 */

/* Nothing may push the page sideways. iframes are in here because the 3D
   backgrounds and the Google map both carry fixed width attributes. */
html, body { max-width: 100%; overflow-x: hidden; }
img, iframe, svg, video { max-width: 100%; }

/* The nav toggle only ever exists below the nav breakpoint. */
/* Colours come from the theme tokens varahi-theme.js publishes on :root, not
   from fixed values: the nav is dark at night but Blue 50 in the daytime
   "dawn" theme, where a hard-coded #E8EEF0 icon is invisible against it.
   The fallbacks are the night values, used only before the theme script runs. */
.nav-toggle {
  display: none; align-items: center; justify-content: center;
  width: 42px; height: 38px; padding: 0;
  background: transparent; border: 1px solid var(--t-navLine, #23383F);
  border-radius: 4px; color: var(--t-navFg, #E8EEF0);
  cursor: pointer; font-family: inherit; line-height: 1;
}
.nav-toggle:focus-visible { outline: 2px solid var(--t-accent, #66B4C4); outline-offset: 2px; }
/* varahi-nav.js draws the icon as an SVG and swaps it for a cross when open,
   so there are no pseudo-element bars to style here. */
.nav-toggle svg { display: block; width: 22px; height: 22px; }

/* A faint fill so the control reads as a button on either a light or a dark
   bar, without committing to a colour of its own. currentColor is the themed
   foreground, so this tracks the bar the same way the icon does. */
.nav-toggle { background: color-mix(in srgb, currentColor 8%, transparent); }
@supports not (color: color-mix(in srgb, red 50%, blue)) {
  .nav-toggle { background: transparent; }
}


@media (max-width: 1080px) {
  section, footer { padding-left: 40px !important; padding-right: 40px !important; }
}


@media (max-width: 900px) {
  section, footer { padding-left: 30px !important; padding-right: 30px !important; }

  /* auto-fit does not save a track whose minimum exceeds the container: a
     minmax(400px,1fr) column still demands 400px and pushes the page wide.
     Collapse the roomiest tracks first. */
  [style*="minmax(440px"], [style*="minmax(420px"], [style*="minmax(400px"],
  [style*="minmax(380px"], [style*="minmax(360px"] {
    grid-template-columns: 1fr !important;
  }

  /* Column gaps sized for a two-up layout are dead space once stacked. */
  [style*="gap:56px"] { gap: 40px !important; }
}


@media (max-width: 760px) {
  section, footer { padding-left: 24px !important; padding-right: 24px !important; }

  [style*="minmax(340px"], [style*="minmax(300px"], [style*="minmax(280px"],
  [style*="minmax(260px"], [style*="minmax(230px"] {
    grid-template-columns: 1fr !important;
  }

  /* Heroes are sized in viewport-independent px, so on a short phone screen
     they reserve more height than the copy needs. */
  [style*="min-height:760px"], [style*="min-height:660px"],
  [style*="min-height:620px"], [style*="min-height:560px"] {
    min-height: auto !important;
  }
  /* Hero padding is set once, further down, next to the type scale it has to
     work with — two rules in two blocks meant the later one silently won. */

  /* --- nav collapses to a toggle ------------------------------------- */
  /* The toggle is positioned against the bar, not laid out inside it. The nav
     carries its own inline flex rules (and support.js can re-render index.html's
     nav underneath us), so any layout that depends on wrap, gap or auto margins
     behaving is fragile — a pinned button cannot drop to a second row. */
  nav[data-themed-nav] {
    position: fixed !important;
    display: flex !important;
    flex-wrap: nowrap !important;
    align-items: center !important;
    min-height: 58px;
    padding-top: 9px !important;
    padding-bottom: 9px !important;
  }
  /* The logotype is deliberately NOT scaled down: BUILD-BRIEF.md sets a 120px
     minimum width, below which the code device stops resolving, and it ships as
     a 269x85 raster with no vector master. At its authored 126px it still fits
     beside the toggle inside a 320px viewport, so there is nothing to gain. */
  .nav-toggle {
    position: absolute !important;
    top: 10px !important;
    right: clamp(20px, 4vw, 56px) !important;
    margin: 0 !important;
  }
  nav[data-themed-nav] > div {
    display: none !important;
    order: 3; width: 100%; flex-direction: column !important;
    align-items: flex-start !important; gap: 4px; padding: 14px 0 6px;
  }
  nav[data-themed-nav].nav-open { flex-wrap: wrap !important; }
  nav[data-themed-nav].nav-open > div { display: flex !important; padding-top: 8px; }
  nav[data-themed-nav] > div > a { padding: 9px 0; font-size: 15px !important; }
  /* The last link is the "Talk to an engineer" / "Apply" button on every page.
     The rule above strips side padding from all links for the stacked menu,
     which left the button's label touching its own edges. Give it back its
     padding and a little air above the plain links. */
  nav[data-themed-nav] > div > a:last-child {
    padding: 12px 22px !important;
    margin-top: 10px;
    align-self: flex-start;
  }
  .nav-toggle { display: inline-flex; }

  /* A fixed nav that has grown a menu must not eat the whole screen. */
  nav[data-themed-nav].nav-open { max-height: 88vh; overflow-y: auto; }

  /* The 3D layers are decorative and expensive on a phone GPU; keep them, but
     stop them dictating height. */
  iframe[data-3d-layer], iframe[data-3d-panel] { height: 100% !important; }
}


@media (max-width: 560px) {
  section, footer { padding-top: 60px !important; padding-bottom: 60px !important; }

  /* Below this width no two-column arrangement is readable. */
  [style*="grid-template-columns"] { grid-template-columns: 1fr !important; }
  [style*="gap:56px"], [style*="gap:48px"], [style*="gap:44px"] { gap: 30px !important; }

  /* Rows of buttons and chips wrap instead of overflowing. */
  section [style*="display:flex"], footer [style*="display:flex"] { flex-wrap: wrap; }

  /* Cards carry desktop padding that wastes a third of a phone's width. */
  [style*="padding:34px"], [style*="padding:32px"], [style*="padding:30px"] {
    padding: 24px !important;
  }
  [style*="padding:26px"], [style*="padding:28px"] { padding: 22px !important; }

  /* Forms: full-width controls, and buttons that are not hit-or-miss. */
  .submit, .again, .quiet-link { width: 100%; justify-content: center; }
  .pane { min-height: 260px !important; }

  /* The map is the one element with a hard pixel height of its own. */
  iframe[src*="google.com/maps"] { height: 300px !important; }
}


@media (max-width: 380px) {
  section, footer { padding-left: 18px !important; padding-right: 18px !important; }
  [style*="padding:34px"], [style*="padding:32px"], [style*="padding:30px"],
  [style*="padding:28px"], [style*="padding:26px"] { padding: 18px !important; }
}


/* A phone in landscape is short, not narrow: heroes must not fill it. */
@media (max-height: 520px) and (orientation: landscape) {
  [style*="min-height:760px"], [style*="min-height:660px"],
  [style*="min-height:620px"], [style*="min-height:560px"] {
    min-height: auto !important;
  }
  section[data-celestial] { padding-top: 104px !important; padding-bottom: 48px !important; }
  [style*="padding:180px 56px"] { padding: 104px 32px 48px !important; }
}


/* Anyone who has asked for less motion should not get a parallax 3D backdrop
   or a spinner racing in the corner. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important; animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important; scroll-behavior: auto !important;
  }
  /* The spinner is the exception: a frozen spinner reads as a hung page. Slow
     it right down instead of stopping it, matching what careers.js/contact.js
     already do for this preference. */
  .spinner { animation-duration: 2.4s !important; animation-iteration-count: infinite !important; }
}


/* ===================================================================
 * Second pass: the things attribute selectors on inline styles cannot
 * reach, plus touch behaviour. Everything above targets style="…";
 * these are class rules from the pages' own <style> blocks, so they
 * need naming directly.
 * =================================================================== */

/* .mod is the two-up copy/visual row on seven pages, declared in the page
   stylesheets as repeat(auto-fit, minmax(400px,1fr)) — the same track minimum
   that overflows a phone, and invisible to the [style*="minmax(400px"] rules
   above because it is a class, not an inline style.
   .step is deliberately left alone: its "auto 1fr" is a narrow number column
   beside the text, which reads correctly at any width. Collapsing it would
   push each number onto a line of its own for no gain. */
@media (max-width: 900px) {
  .mod { grid-template-columns: 1fr !important; gap: 32px !important; }
}

@media (max-width: 760px) {
  /* The 3D layers sit over the hero with pointer-events:auto so a mouse can
     drag to orbit them. On a touch screen that same setting swallows the swipe
     used to scroll, and a visitor who starts their drag on the hero cannot get
     down the page. Orbiting is a nicety; scrolling is not, so on touch-sized
     screens the layer goes inert and the hero scrolls like any other section.
     The model keeps animating — only interaction is dropped. */
  iframe[data-3d-layer], iframe[data-3d-panel] { pointer-events: none !important; }

  /* The 3D stop/step buttons drive that same layer via postMessage, not touch,
     so they stay live and remain the way to change the model on a phone. */
  [data-3d], [data-3d-step], [data-3d-stop] { pointer-events: auto !important; }

  /* A 420px viewer is most of a phone screen for something decorative. */
  .viz iframe { height: 300px !important; }
}

@media (max-width: 560px) {
  .viz iframe { height: 230px !important; }

  /* nowrap keeps desktop buttons and chips on one line; on a narrow screen it
     is what pushes a long label past the edge. Nav links keep theirs — they
     are short and the collapsed menu stacks them anyway. */
  section [style*="white-space:nowrap"] { white-space: normal !important; }

  /* Long unbroken strings — an email address, a Drive URL pasted into copy —
     have nothing to wrap on and will widen the page on their own. */
  p, li, td, .pane-b, .hint { overflow-wrap: anywhere; }

  /* Two inline paddings are written with a space after the colon, which the
     [style*="padding:34px"] selectors above do not match. */
  [style*="padding: 34px"], [style*="padding: 32px"] { padding: 24px !important; }
}


/* ===================================================================
 * Hero and display type.
 *
 * Every clamp() in the markup is tuned for desktop: the vw term is small
 * (4.4vw) and the floor is large (40px), so on a 360px phone the clamp
 * pins to its minimum and the headline stays desktop-sized. .year floors
 * at 60px, .big at 34px. Re-clamp them with a floor that suits a phone
 * and a vw term steep enough to actually do the scaling.
 * =================================================================== */

@media (max-width: 760px) {
  h1, [data-hero-title] {
    font-size: clamp(27px, 7.4vw, 40px) !important;
    line-height: 1.14 !important;
    letter-spacing: -0.02em !important;
  }
  h2, [style*="clamp(31px"], [style*="clamp(30px"], [style*="clamp(34px"] {
    font-size: clamp(23px, 5.8vw, 32px) !important;
    line-height: 1.18 !important;
  }
  h3 { font-size: 19px !important; }
  .big  { font-size: clamp(26px, 7vw, 40px) !important; line-height: 1.14 !important; }
  .year { font-size: clamp(40px, 14vw, 84px) !important; }

  .lede, [data-hero-lead] { font-size: 17px !important; line-height: 1.55 !important; }
  .sub,  [data-hero-sub]  { font-size: 15.5px !important; }
  .body, .story           { font-size: 16.5px !important; line-height: 1.62 !important; }

  /* Measures written in ch assume a desktop column and now just add nothing. */
  [style*="max-width:60ch"], [style*="max-width:58ch"], [style*="max-width:62ch"],
  [style*="max-width:66ch"], [style*="max-width:72ch"], [style*="max-width:74ch"],
  [style*="max-width:78ch"], [style*="max-width:680px"], [style*="max-width:700px"],
  [style*="max-width:720px"] { max-width: 100% !important; }

  /* The hero's 180px of top padding clears a two-row desktop nav; the
     collapsed bar is a single row. */
  /* Matched on data-celestial, not on the inline padding string: every hero
     carries that attribute, whereas a [style*="padding:180px 56px"] selector
     depends on the exact text of an inline style — and support.js re-serialises
     index.html's style attributes, so the spacing there is not ours to rely on.
     The nav is fixed and 58px tall, so this top padding is clearance: 156 leaves
     roughly 98px of actual air above the kicker. */
  section[data-celestial] {
    padding-top: 156px !important;
    padding-left: 24px !important;
    padding-right: 24px !important;
    padding-bottom: 64px !important;
  }
  [style*="padding:180px 56px"] { padding: 156px 24px 64px !important; }
}

@media (max-width: 560px) {
  h1, [data-hero-title] { font-size: clamp(25px, 8vw, 33px) !important; }
  .year { font-size: clamp(34px, 15vw, 62px) !important; }
  section[data-celestial] {
    padding-top: 144px !important;
    padding-left: 20px !important;
    padding-right: 20px !important;
    padding-bottom: 52px !important;
  }
  [style*="padding:180px 56px"] { padding: 144px 20px 52px !important; }

  /* The hero chip row is four buttons wide on desktop; let it become two. */
  [data-3d-target] { font-size: 12px !important; }
}


/* ===================================================================
 * The celestial control (sun / evening / night) beside the hamburger.
 *
 * theme.js mounts it inside the hero, absolutely positioned at top:104px
 * right — which on a phone lands on the headline. It is repositioned here
 * with CSS only. It is NOT moved in the DOM: support.js patches index.html
 * and expects the node in the hero it rendered, so reparenting it made a
 * later patch call removeChild against the wrong parent and throw.
 *
 * position:fixed takes it out of the hero's flow and aligns it to the
 * viewport, like the nav bar itself. The right offset clears the toggle:
 * the nav's own side padding, plus the 42px button and a 10px gap.
 * =================================================================== */
@media (max-width: 760px) {
  [data-celestial-btn] {
    position: fixed !important;
    top: 10px !important;
    right: calc(clamp(20px, 4vw, 56px) + 52px) !important;
    left: auto !important; bottom: auto !important;
    width: 38px !important; height: 38px !important;
    opacity: 1 !important;
    z-index: 60 !important;   /* the nav itself is 50 */
  }
  [data-celestial-btn] svg { width: 36px !important; height: 36px !important; }
}


/* In-page anchors (index jumps to #varahione, #physical-ai and so on) scroll the
   target to y=0, which is behind the fixed nav. scroll-margin-top reserves the
   bar's height plus a little air, so a jumped-to heading is not clipped. */
section[id] { scroll-margin-top: 84px; }
@media (max-width: 760px) { section[id] { scroll-margin-top: 74px; } }
