/* ==========================================================================
   OOGLE V5 — DESIGN TOKENS

   The system in four rules.

   1. LIGHT IS THE DEFAULT GROUND. V4 was a dark diagnostic bay. V5 is a
      light, generously spaced document with dark sections used deliberately
      for weight and punctuation. Authority here comes from space, not from
      turning the lights off.

   2. ONE BLUE CARRIES THE BRAND. --blue (#0E61D1) is the Oogle blue: links,
      primary actions, marks, rules. --cyan (#00BFFF) is a signal, not a
      second brand color. It appears only as a hairline, a tick, or a focus
      ring, and never as type. Deeper blues exist to give gradients somewhere
      to go, and gradients are rationed.

   3. SOFT SURFACES, SQUARE MARKS. (V5.9.2) Anything a person touches or
      reads inside is rounded: buttons and chips are pills, fields and
      content insets sit at 12px, cards at 16px, the largest panels at 20px.
      Every value comes from the --radius-* scale below; nothing states its
      own number. What stays SQUARE is the brand: the pixel field, the 8px
      dots, the keyline (a 2px blue rule above a section eyebrow) and the
      corner bracket. That contrast, soft container / precise mark, is the
      design language, so never round a pixel and never pill a panel.

   4. TWO GROUNDS, ONE SET OF NAMES. Every semantic token is defined for the
      light ground on :root and re-pointed inside .on-dark. Components never
      ask which ground they are on.
   ========================================================================== */

:root {

  /* ---- Families ---------------------------------------------------------- */
  --font-sans: "Archivo", "Archivo Fallback", -apple-system, BlinkMacSystemFont,
               "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-mono: "DM Mono", "DM Mono Fallback", ui-monospace, "SF Mono",
               SFMono-Regular, Menlo, Consolas, monospace;

  /* ---- Light ground ------------------------------------------------------- */
  --white:    #FFFFFF;
  --paper:    #FFFFFF;
  --paper-2:  #F7F9FC;
  --paper-3:  #EFF3F9;
  --sand:     #F6F4F1;   /* the one warm ground. Exactly one movement uses it. */
  --sand-2:   #EDE9E3;

  /* ---- Deep navy ---------------------------------------------------------- */
  --navy:     #07111F;
  --navy-2:   #0A1729;
  --navy-3:   #0E1E33;
  --navy-4:   #14263E;
  --navy-5:   #1A3050;

  /* ---- Blue. One primary, one accent, two for depth. ---------------------- */
  --blue:        #0E61D1;   /* the Oogle blue */
  --blue-deep:   #0A47A2;
  --blue-far:    #1432BA;   /* gradient terminus only */
  --blue-lift:   #2A72DC;   /* 4.63:1 on #FFF — was #2E7BE8 at 4.11:1, below AA */
  --blue-light:  #6FB2F7;   /* type weight on navy */
  --blue-pale:   #A9CFFB;
  --cyan:        #00BFFF;   /* signal only: rules, ticks, focus */
  --cyan-soft:   #7FDFFF;

  --blue-film:   rgba(14, 97, 209, 0.07);
  --blue-film-2: rgba(14, 97, 209, 0.13);
  --cyan-film:   rgba(0, 191, 255, 0.14);
  --dark-film:   rgba(255, 255, 255, 0.055);
  --dark-film-2: rgba(255, 255, 255, 0.10);

  /* ---- Ink on light ------------------------------------------------------- */
  --ink:    #09101C;
  --ink-2:  #1C2839;
  --ink-3:  #3D4C63;
  --ink-4:  #566579;   /* AA on white and on --paper-2 at 15px */
  --ink-5:  #647287;   /* hairline icons and 18px+ type */

  /* ---- Type on navy ------------------------------------------------------- */
  --snow:   #EAF1FA;
  --snow-2: #B4C6DC;
  --snow-3: #93A9C4;   /* AA on every navy surface at 15px */
  --snow-4: #86A0BE;   /* AA on every navy surface */

  /* ---- Lines -------------------------------------------------------------- */
  --line:      #DDE4EE;
  --line-2:    #C6D2E2;
  /* Control edges are not decoration: WCAG 1.4.11 wants 3:1 against whatever
     is behind them. The old outline-button borders measured 1.53:1 on white
     and 1.43:1 on navy, so on the hero the secondary action had no readable
     boundary at all. These clear 3:1 on every ground the site actually uses
     (white, --paper-2, --sand / --navy, --navy-2, --navy-3). */
  --edge:      #78889E;
  --edge-dark: #546C92;
  --line-dark: #1C314C;
  --line-dark-2: #294869;

  /* ---- States. Used inside artifacts, never as page chrome. --------------- */
  --ok:        #0B7A55;
  --ok-dark:   #3FD39B;
  --warn:      #8F5908;
  --warn-dark: #E9AE45;
  --fault:     #B32D1D;
  --fault-dark:#FF8A73;
  --ok-film:   rgba(11, 122, 85, 0.10);
  --warn-film: rgba(162, 101, 11, 0.10);
  --fault-film:rgba(179, 45, 29, 0.09);

  /* ---- Semantic, light ground (the default) ------------------------------- */
  --bg:          var(--paper);
  --bg-2:        var(--paper-2);
  --surface:     var(--paper);
  --surface-2:   var(--paper-2);
  --text:        var(--ink);
  --text-2:      var(--ink-2);
  --text-dim:    var(--ink-3);
  --text-faint:  var(--ink-4);
  --rule:        var(--line);
  --rule-strong: var(--line-2);
  --control-edge: var(--edge);
  --link:        var(--blue);
  --link-hover:  var(--blue-deep);
  --mark:        var(--blue);
  --keyline:     var(--blue);
  --focus:       var(--blue);
  --state-warn:  var(--warn);
  --state-fault: var(--fault);
  --state-ok:    var(--ok);
  --film:        var(--blue-film);

  /* ---- Type scale -----------------------------------------------------------
     One display recipe repeated at every size: 900 weight, -0.042em tracking,
     0.94 line-height, 94% width. Repetition is what reads as intent. The
     scale that shipped in V5.9.5 changed weight, tracking AND line-height at
     every step, so nothing repeated and the page had no signature.

     The 34px step (--t-h3) is new. Without it the page jumped 72 -> 48 -> 17
     and the four words that ARE the company (Build, Support, Grow, AI) had
     nowhere to sit. Floors are raised: a headline should fill its measure on a
     phone, not shrink out of the way. --t-body never shrinks at all. */
  --t-mega:    clamp(3.5rem,   2.55rem  + 4.20vw, 6.75rem);  /*  56 -> 108 */
  --t-display: clamp(2.5rem,   1.95rem  + 2.45vw, 4.5rem);   /*  40 ->  72 */
  --t-h2:      clamp(1.875rem, 1.55rem  + 1.45vw, 3rem);     /*  30 ->  48 */
  --t-h3:      clamp(1.375rem, 1.16rem  + 0.95vw, 2.125rem); /*  22 ->  34 */
  --t-h4:      clamp(1.1875rem,1.12rem  + 0.29vw, 1.5rem);   /*  19 ->  24 */
  --t-lead:    clamp(1.1875rem,1.10rem  + 0.38vw, 1.375rem); /*  19 ->  22 */
  --t-body:    1.0625rem;   /* 17 — fixed at every width */
  --t-sm:      0.9375rem;   /* 15 */
  --t-xs:      0.875rem;    /* 14 — nothing a reader reads goes below this */
  --t-eyebrow: 0.8125rem;   /* 13 */
  --t-mono:    0.8125rem;   /* 13 */

  /* ONE display line-height and ONE display tracking. Do not add a third. */
  --lh-display: 0.94;
  --tr-display: -0.042em;
  /* The width axis was set to 94/86% so headlines would "fill the measure".
     Measured, it did the opposite: at 390px, 86% took the longest line from
     79% of the column to 69%, and it narrows the space glyph as well, so with
     -0.042em tracking on top the words in "stop here." ran together. The
     headline fills its measure by being given a tighter max-width instead. */
  --wd-display: 100%;   /* kept as a hook; the shipped face has no width axis */
  /* Display tracking this tight closes word gaps faster than letter gaps.
     Measured at 66px: an 8.19px word space against a -0.02px median letter
     gap. The words need the difference put back. */
  --ws-display: 0.10em;
  --ws-caps:    0.20em;   /* tracked uppercase needs proportionally more */

  --lh-mega:  var(--lh-display);
  --lh-disp:  var(--lh-display);
  --lh-h2:    var(--lh-display);
  --lh-h3:    1.04;
  --lh-lead:  1.5;
  --lh-body:  1.65;
  --lh-tight: 1.35;

  --tr-mega:  var(--tr-display);
  --tr-disp:  var(--tr-display);
  --tr-h2:    var(--tr-display);
  --tr-h3:    var(--tr-display);
  --tr-h4:    -0.028em;
  --tr-text:  -0.011em;
  --tr-eyebrow: 0.14em;
  --tr-mono:  0.06em;

  /* Weights. 600 is gone: at 15px it read as 400 with a smudge, and it was
     doing the job that case, tracking and colour should do. */
  --w-book:  400;   /* all prose */
  --w-mid:   500;   /* mono only */
  --w-semi:  700;   /* alias kept so nothing that still says --w-semi breaks */
  --w-bold:  700;   /* nav, buttons, inline strong */
  --w-black: 900;   /* every display size, every label, the wordmark */

  /* ---- Space. 4px base. --------------------------------------------------- */
  --s1: 4px;    --s2: 8px;    --s3: 12px;   --s4: 16px;
  --s5: 20px;   --s6: 24px;   --s7: 32px;   --s8: 40px;
  --s9: 48px;   --s10: 64px;  --s11: 80px;  --s12: 96px;
  --s13: 120px; --s14: 144px; --s15: 176px; --s16: 208px;

  /* ---- Measure ------------------------------------------------------------ */
  --track:      1280px;
  --track-wide: 1440px;
  --track-text: 68ch;
  --measure:    760px;   /* the article column */
  --gutter:     clamp(20px, 4vw, 64px);

  /* ---- Geometry. One scale, keyed to how big the surface is. -------------
     V5.11: the ladder had no top. --radius-card (16px) was carrying thirteen
     of twenty-four uses and the largest tier, 20px, was spent on a menu and a
     form shell. Nothing on the site was a large defined surface, so the only
     thing with a silhouette was the artwork -- which is exactly why the
     artwork read as the whole visual language. Two tiers added at the top;
     everything below them is unchanged.

     feature  32  the page-scale objects: hero, closer, work feature, statement
     panel    24  section-internal containers: groups of things, framed figures
     card     16  content cards, screenshots, plates
     inset    12  blocks inside a reading column: callouts, tables, notes
     control  10  small controls: burger, menu rows, skip link, inputs
     chip      6  inline code -- the one mark smaller than a control
     pill    999  buttons, chips, tags, filters, radio-chips, the nav hover
     Brand marks (pixels, dots, keylines, brackets) take no radius at all.
     Full-bleed bands take none either: a band has no corners to round. */
  --radius-pill:    999px;
  --radius-chip:    6px;    /* inline code and other sub-control marks */
  --radius-control: 10px;
  --radius-input:   12px;
  --radius-inset:   12px;
  --radius-card:    16px;
  --radius-panel:   24px;
  --radius-feature: 32px;

  /* ---- Surfaces -----------------------------------------------------------
     A defined surface on a light ground is a 1px line and generous padding,
     not a drop shadow. Ground-to-fill contrast is deliberately near zero
     (#FFF on #F7F9FC is 1.05:1) so the eye finds the EDGE, which is what
     reads as precision rather than as a floating card. Border and fill
     contrast are substitutes, never stacked: a navy or blue surface on a
     light page has 15:1 of fill contrast and therefore takes no border.
     One shadow value exists. It is navy-tinted, 5% alpha, zero spread, and
     it is a seasoning -- if a surface needs more definition it gets a border
     or a fill, never a second shadow. */
  --surface-edge: var(--line);
  /* The lift a feature panel gets. Declared HERE and nowhere else, because the
     .on-dark block re-points --lift-3 to the value for something sitting on
     navy -- and every feature panel on this site sits on the white page. The
     hero shipped that dark shadow onto white for exactly one release. */
  --panel-lift: 0 4px 10px rgba(9, 16, 28, 0.05),
                0 28px 64px -28px rgba(9, 16, 28, 0.30);

  /* ---- Motion -------------------------------------------------------------
     Amplitude is legible or absent. A 12px move on a 104px headline is not a
     move, it is a fade with extra steps — V5.9.5 shipped exactly that, and
     three of its four reveals never ran at all. Travel is >= 24px or the
     motion is deleted.

     prefers-reduced-motion is handled ONCE, at the bottom of this file, by
     collapsing these numbers. Components never write a second media query. */
  --m-tap:    90ms;
  --m-state: 160ms;
  --m-panel: 240ms;
  --m-enter: 620ms;
  --m-scene: 900ms;
  --m-demo: 1500ms;

  --e-out:   cubic-bezier(0.16, 1, 0.30, 1);   /* arrivals. no overshoot ever */
  --e-inout: cubic-bezier(0.65, 0, 0.35, 1);
  --e-snap:  cubic-bezier(0.85, 0, 0.15, 1);   /* alignment, pixels, repair */

  --m-rise:    28px;
  --m-rise-lg: 40px;
  --m-nudge:    4px;
  --m-step:    90ms;

  /* Legacy names, kept for one release so nothing breaks mid-refactor. */
  --d-tap:   var(--m-tap);
  --d-state: var(--m-state);
  --d-enter: var(--m-enter);
  --d-scene: var(--m-scene);
  --ease:     var(--e-out);
  --ease-io:  var(--e-inout);
  --ease-std: var(--e-inout);

  /* ---- Depth. Light-ground elevation is a shadow; on navy it is a line. --- */
  --lift-1: 0 1px 2px rgba(9, 16, 28, 0.05);
  --lift-2: 0 2px 4px rgba(9, 16, 28, 0.04), 0 12px 28px -14px rgba(9, 16, 28, 0.22);
  --lift-3: 0 4px 10px rgba(9, 16, 28, 0.05), 0 28px 64px -28px rgba(9, 16, 28, 0.34);
  --lift-blue: 0 12px 30px -14px rgba(14, 97, 209, 0.42);

  /* The arrow glyph, once, so anything that needs it stops re-inlining the
     same 180-byte data URI. */
  --arrow-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 8'%3E%3Cpath d='M0 4h14M11 1l3 3-3 3' fill='none' stroke='%23000' stroke-width='1.4'/%3E%3C/svg%3E");

  --hdr-h: 74px;
}

/* --------------------------------------------------------------------------
   THE DARK GROUND
   Anything inside .on-dark re-points the semantic tokens. Components are
   written once and never test which ground they are sitting on.

   .bluefield is deliberately NOT here — white on Oogle blue is its own set of
   values and lives in art.css beside the field that needs it. V5.10 moved
   .closer onto that blue ground for the same reason, so it left this list too.
   -------------------------------------------------------------------------- */

/* The one token those two grounds DO have to re-point. Both carried
   `.closer :focus-visible { outline-color: #fff }` rules instead, and V5.20
   found the minifier had been silently deleting the space in that selector --
   150 controls on 51 pages shipped a blue focus ring on a blue panel at
   1.6:1. The minifier is fixed (build.py, _collapse_delims), and the ring is
   re-pointed at the token here as well, because a focus indicator should not
   depend on one descendant selector surviving a text transform. */
.closer, .closer-panel, .bluefield { --focus: #fff; }
.on-dark,
.hero-panel,
.phero-service .phero-panel,
.phero-portfolio .phero-panel,
.phero-lp .phero-panel,
.lp-ftr,
.ftr {
  --bg:          var(--navy);
  --bg-2:        var(--navy-2);
  --surface:     var(--navy-3);
  --surface-2:   var(--navy-4);
  --text:        var(--snow);
  --text-2:      var(--snow);
  --text-dim:    var(--snow-2);
  --text-faint:  var(--snow-3);
  --rule:        var(--line-dark);
  --rule-strong: var(--navy-5);
  --surface-edge: var(--line-dark);
  --control-edge: var(--edge-dark);
  --link:        var(--blue-light);
  --link-hover:  var(--cyan-soft);
  --mark:        var(--blue-light);
  --keyline:     var(--cyan);
  --focus:       var(--cyan);
  --state-warn:  var(--warn-dark);
  --state-fault: var(--fault-dark);
  --state-ok:    var(--ok-dark);
  --film:        var(--dark-film);
  --lift-1: none;
  --lift-2: 0 18px 44px -22px rgba(0, 0, 0, 0.7);
  --lift-3: 0 30px 70px -30px rgba(0, 0, 0, 0.8);

  background: var(--bg);
  color: var(--text);
}

/* --------------------------------------------------------------------------
   BREAKPOINTS
   Five, and only five: 1280 / 1024 / 768 / 600 / 430. V5.9.5 shipped fifteen
   distinct max-widths because components were nudged one at a time.
   -------------------------------------------------------------------------- */
@media (max-width: 600px) {
  :root { --hdr-h: 62px; }
}

/* --------------------------------------------------------------------------
   REDUCED MOTION — the whole system, in one place.
   Collapsing the tokens removes every reveal, every stagger and every travel
   without a single component needing to know. What remains is the page at its
   final state, which is the page the static design was drawn for.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  :root {
    --m-enter: 1ms;  --m-scene: 1ms;  --m-demo: 1ms;  --m-panel: 1ms;
    --m-rise: 0px;   --m-rise-lg: 0px; --m-nudge: 0px; --m-step: 0ms;
  }
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    scroll-behavior: auto !important;
  }
}
