/* Nat Luby Electrical - design tokens, compiled from design/DNA.md.
   Components consume these ONLY. A hardcoded colour at the point of use is a
   build error (rk:design-dna).

   05.08.26 - LIGHT LANE, and the feature colour is the LOGO'S (rk:page-field,
   rk:brand-colour-fidelity). Two corrections in one day, both from Josh:

   1. "the whole thing is green and it looks overwhelming." In either lane the
      brand hue is never the field. Sections break apart on a barely-there tint
      of the brand hue, never a second colour: white base, near-white steps.
   2. The dominant green was the hi-vis fluoro, sampled from a stripe in a
      PHOTOGRAPH, not the logo's own green. Close enough is not the same. The
      primary feature colour now comes from the logo artwork, with two
      ANALOGOUS relatives so one hue does not tire the page.

   The ladder below is GENERATED, not hand-picked:
     python3 agency-core/tools/brand-colour/sample.py \
       assets/brand/LOGO-nat-luby-electrical-full-colour.svg --lane light */

:root {
  /* ── FEATURE COLOUR: the logo's own, sampled from the artwork ─────────
        PRIMARY, from LOGO-nat-luby-electrical-full-colour.svg, 50.0% of logo
        pixels (rk:brand-colour-fidelity). Buttons, icons, links, rules. */
  --brand:        #67A051;
  --brand-soft:   #90B881;
  --brand-deep:   #446B34; /* white clears 6.2:1 here, so text-bearing surfaces
                              and links on white use this relative of the same
                              hue rather than a different colour */
  --accent:       #67833B; /* analogous, hue -20deg */
  --accent-2:     #86BD89; /* analogous, hue +20deg */
  --nle-ink:      #000106; /* the lightning bolt, same artwork, 50.0% */

  /* Hi-vis fluoro, sampled from the client's own vehicle livery (the NLE01 /
     NLE02 door panels). DEMOTED to a minor accent: it is not the brand, and it
     now appears only as the live edge on dark plate, where the hi-vis metaphor
     is doing real work (the lockout tag's isolation stripe, the hazard rules). */
  --nle-fluoro:      #C6E23F;
  --nle-fluoro-hot:  #DDF652;

  /* ── THE FIELD, light lane (rk:page-field) ────────────────────────────
        Near-white steps carrying a WHISPER of the logo hue, so sections
        separate without a second colour entering the page. Generated by
        sample.py, never hand-picked. */
  --lane:      "light";
  --field:     #FFFFFF;
  --field-2:   #F8F9F8;
  --field-3:   #F3F4F3;
  --field-4:   #ECEFEC;
  --rule-hair: #E2E6E2;

  /* ── FEATURE SURFACES (rk:field-vs-feature). The field is the page and its
        bands; these are the things the eye should GO to. A white form on a
        white page is invisible, so every one of these differs in value from
        the field. */
  --feature-chrome: #2C4723;  /* header glass + the pancake band */
  --feature-tint:   #EDF3EA;  /* brand-tinted step behind white cards */
  --feature-card:   #F4F8F2;  /* the quote card, lifted off the field */
  --feature-faq-deep: color-mix(in srgb, var(--brand-deep) 55%, var(--feature-chrome));

  /* ── the button, in its two contexts. ONE shape site-wide; the fill flips
        because --brand-deep on the deep-green pancake would disappear into it.
        Declared as a pair so no component invents a third button colour. */
  --btn-bg:          var(--brand-deep);
  --btn-bg-hover:    var(--brand);
  --btn-ink:         var(--paper);
  --btn-bg-on-deep:       var(--accent-2);
  --btn-bg-on-deep-hover: var(--brand-soft);
  --btn-ink-on-deep:      var(--steel-950);

  /* ── steel: dark PLATES only, never the field. Hue held at the logo's
        103deg, so a dark band still reads as this brand and not as black
        (rk:brand-derived-dark-surfaces). ─────────────────────────────────── */
  --steel-900: #131C0F;  /* photo-band base, FAQ cards. lum 25, spread 13 */
  --steel-800: #1A2515;  /* raised dark plate. lum 33, spread 16 */
  --steel-700: #22301B;  /* dark hover. lum 42, spread 21 */
  --steel-600: #2F4126;
  --steel-500: #415734;
  --steel-950: #0D140A;  /* the footer floor */

  /* ── text ───────────────────────────────────────────────────────────── */
  --ink:          #1A2214;  /* on --field (white) 15.9:1 */
  --graphite:     #4E5747;  /* secondary on --field 7.2:1 */
  --ink-quiet:    #67715F;  /* fine print on --field 5.1:1 */
  --on-deep:      #E9EFE4;  /* on --steel-900 14.9:1 */
  --on-deep-soft: #A6B29B;  /* on --steel-900 7.8:1 */

  /* ── type ────────────────────────────────────────────────────────────── */
  /* DISPLAY FACE: Sora, 06.08.26. Saira 800 in caps with open tracking read
     blocky - Josh: "looks a bit like 8 bit". Sora keeps the logo's geometry
     (flat terminals, wide even counters, an upright angular skeleton) but its
     joins are cleaner and its curves tighter, so at weight it reads modern and
     minimal rather than pixelly. Weight drops 800 -> 700 and tracking tightens,
     which is most of the difference: the blockiness was as much the spacing as
     the face. */
  --font-display: 'Sora', system-ui, sans-serif;
  --font-body:    'IBM Plex Sans', system-ui, sans-serif;

  --fs-display: clamp(2rem, 1.2rem + 3.4vw, 3.4rem);
  --fs-h1:      clamp(1.75rem, 1.2rem + 2.2vw, 2.6rem);
  --fs-h2:      clamp(1.4rem, 1.1rem + 1.3vw, 1.95rem);
  --fs-h3:      clamp(1.05rem, .98rem + .4vw, 1.2rem);
  --fs-body:    clamp(1rem, .97rem + .15vw, 1.06rem);
  --fs-small:   .875rem;
  --fs-btn:     1rem;

  --tracking-display: .005em;
  --leading-body: 1.65;

  /* HEADING RHYTHM, set once and used by the shared heading rule: below is
     always smaller than above (rk:heading-rhythm).

     06.08.26 - these were viewport clamps, and a heading's air is not a
     property of the viewport, it is a property of the HEADING. The two curves
     came apart at tablet: --fs-h1 hit its 2.6rem ceiling at 1024px while
     --head-below was still climbing on vw, so a 42px H1 shipped with 14px
     under it and failed the 0.45x floor on exactly the two viewports nobody
     looks at. Expressed in em they cannot come apart at any width, because
     they are the same measurement. */
  --head-above: 1.5em;
  --head-below: .55em;
  /* a card title is still a heading in a smaller room: same ratio underneath,
     and its air ABOVE is the icon's own margin rather than a text margin */
  --head-above-card: 16px;

  /* ── shape: ONE CORNER LANGUAGE, derived from the header ──────────────
     06.08.26. The 05.08.26 doctrine was `--radius: 0` everywhere ("plate steel
     is cut and welded, not moulded") sitting beside a mandatory 14px detached
     header bar. That is not a material argument, it is a contradiction: the
     one piece of chrome on every page disagreed with every control under it,
     and the house rule is explicit - "ONE corner language across the site:
     buttons, cards and panels echo the header's curvature. Form fields take a
     slighter radius than the large surfaces" (slots.json _house_global). The
     detached curved header is a blanket rule and cannot move, so the scale is
     derived DOWN from it rather than the site being left in two minds.

     It survives as a material fact, not a concession. This client's own
     signature object is a die-cut lockout tag: a printed safety tag is
     radiused at every corner precisely so it does not catch or tear on plant.
     Formed sheet metal, machine guards and switchboard escutcheons all carry a
     bend radius. Zero-radius was the borrowed web convention here, not the
     other way round.

     The scale steps DOWN with the surface: chrome > card/plate > control >
     field. Every corner of any one control still matches every other corner of
     it - the chamfer stays gone (rk:button-symmetry). The 45deg cut survives
     ONLY as the section-edge hazard motif, where no control is involved. */
  --r-chrome:    20px;  /* the detached header bar: the reference curvature.
                           HOUSE NUMBER, slots.json header.reference_measurements,
                           measured off Only Concrete 06.08.26. Not ours to pick. */
  --r-card:      14px;  /* service cards, FAQ items, the quote card, tiles */
  --r-plate:     14px;  /* photo plates and dark panels: the card family */
  --r-control:   11px;  /* buttons, the burger, the upload control */
  --r-signature: 11px;  /* the lockout-tag call plate: it IS a control */
  --r-field:      6px;  /* form fields, slighter than the large surfaces */
  --border-plate: 1px solid var(--rule-hair);
  --border-plate-dark: 1px solid var(--steel-600);
  --border-live: 3px solid var(--brand);
  --ctl-h: 46px;
  --ctl-h-lg: 54px;

  /* ── spacing ─────────────────────────────────────────────────────────── */
  --pad-section: clamp(56px, 6.5vw, 96px);
  --pad-gutter:  clamp(20px, 4vw, 44px);
  --shell:       1180px;
  --shell-hero:  1080px;
  --measure:     68ch;
  /* HOUSE DETACHED-HEADER SPEC (slots.json header.reference_measurements,
     measured off Only Concrete 06.08.26). These are NUMBERS, not a style
     choice: "match Only Concrete" was asked twice and missed twice because it
     required going and measuring another site. It may compress on scroll; at
     rest it is exactly these four values. */
  --hdr-bar-h:   96px;    /* panel height at rest */
  --hdr-max-w: 1200px;    /* panel max-width */
  --hdr-inset:   26px;    /* clear of the top of the page */
  --hdr-h:      122px;    /* what the fixed header occupies: 96 + 26 */

  /* ── THE GLASS (Josh 06.08.26: "a lot more transparent and look a lot more
     like actual glass"). Glass is not just a low opacity: it REFRACTS. So the
     tint is thin, the blur is deep, saturation is lifted so what shows through
     reads as bent light rather than dimmed colour, and a specular highlight
     runs along the top edge the way it does on a real curved pane.
     --hdr-tint is driven by scroll in site.js, between these two stops. */
  --hdr-tint-rest:  26%;   /* over the hero photograph: properly see-through */
  --hdr-tint-full:  96%;   /* once the page beneath it is near-white */
  --hdr-blur:       20px;
  --hdr-sat:        170%;

  /* ── THE PUCK. Every control is a small piece of the same glass the header
     is made of: blurred and saturated backdrop, a bright top lip, a soft inner
     floor, and a two-layer cast shadow so it sits ABOVE the page rather than
     printed on it. The tint is higher than the header's because a control
     carries text and has to hold it over any surface. */
  --puck-blur:      14px;
  --puck-sat:       160%;
  --puck-sheen: inset 0 1px 0 color-mix(in srgb, var(--on-deep) 46%, transparent),
                inset 0 0 0 1px color-mix(in srgb, var(--on-deep) 12%, transparent),
                inset 0 -12px 18px -14px color-mix(in srgb, var(--nle-ink) 62%, transparent);
  --shadow-puck: 0 1px 2px color-mix(in srgb, var(--nle-ink) 34%, transparent),
                 0 10px 22px -8px color-mix(in srgb, var(--nle-ink) 46%, transparent);
  --shadow-puck-lift: 0 2px 4px color-mix(in srgb, var(--nle-ink) 30%, transparent),
                      0 18px 34px -10px color-mix(in srgb, var(--nle-ink) 52%, transparent);
  /* the pane's own edges: a bright top lip, a fine ring, and a soft inner floor
     so the glass has thickness rather than being a flat translucent rectangle */
  --glass-sheen: inset 0 1px 0 color-mix(in srgb, var(--on-deep) 42%, transparent),
                 inset 0 0 0 1px color-mix(in srgb, var(--on-deep) 14%, transparent),
                 inset 0 -14px 22px -18px color-mix(in srgb, var(--nle-ink) 55%, transparent);
  --hdr-h-sm:    92px;
  --hero-gap:    clamp(34px, 7vh, 88px);   /* the hero breathes (Josh 07.08.26) */
  --gal-row:     200px;   /* the mosaic's row unit: a wide feature over two */

  /* The split-plate hero geometry token is GONE (06.08.26). The homepage hero
     is always a full-bleed background image (rk:homepage-hero-fullbleed), so
     there is no plate to measure and no copy column to reserve. The whole
     class of bug it was introduced to fix cannot recur, because there is no
     longer a second coordinate system to disagree with. split-plate survives
     as an INTERNAL PAGE variant only. */

  /* PHOTO BAND PARITY (rk:photo-band-parity). Every photo band on the page is
     one height, fixed ONCE here rather than left to fall out of how long each
     section's copy happens to be. Matched UP to the taller of the two. */
  --band-min-h: clamp(430px, 44vw, 580px);


  /* ── motion: mechanical snap, no overshoot ───────────────────────────── */
  --snap: 120ms cubic-bezier(.2, 0, 0, 1);
  --snap-slow: 200ms cubic-bezier(.2, 0, 0, 1);
  --reveal: 620ms cubic-bezier(.16, .84, .44, 1);
  --glint: 420ms cubic-bezier(.2, 0, 0, 1);
  /* the three named animations. A raw duration at the point of use is a build
     error the same way a raw hex is, so they are declared here (rk:design-dna). */
  --spin-ring:  7s linear infinite;               /* the call plate's conic shine */
  --pulse-submit: 4.2s ease-in-out infinite;      /* the Get Quote pulse */
  --draw-tick:  520ms cubic-bezier(.2, 0, 0, 1);  /* the sent-message tick */

  /* ── hazard stripe: the plant-floor marking, band edges only ─────────── */
  --hazard: repeating-linear-gradient(
      45deg,
      rgba(198, 226, 63, .55) 0 10px,
      transparent 10px 20px);

  /* ── industry texture: rolled plate-steel mill grain ─────────────────── */
  --texture-plate: repeating-linear-gradient(
      116deg, rgba(19, 28, 15, .018) 0 1px, transparent 1px 7px);
  --texture-plate-dark: repeating-linear-gradient(
      116deg, rgba(255, 255, 255, .020) 0 1px, transparent 1px 7px);

  /* ── shadows: cast down-right from ONE implied light ─────────────────── */
  --shadow-contact: 2px 3px 7px rgba(19, 28, 15, .16);
  --shadow-cast:    7px 11px 30px rgba(19, 28, 15, .12);
  --shadow-lift:    9px 14px 34px rgba(19, 28, 15, .18);  /* hover, same light */
  --shadow-drop-contact: drop-shadow(2px 3px 7px rgba(0, 0, 0, .55));
  --shadow-drop-cast:    drop-shadow(7px 11px 30px rgba(0, 0, 0, .45));
  --shadow-drop-icon:    drop-shadow(1px 2px 3px rgba(0, 0, 0, .70));
  --shadow-text:    .019em .024em .035em rgba(0, 0, 0, .92),
                    .048em .058em .4em rgba(0, 0, 0, .62);
  --shadow-text-sm: 1px 2px 3px rgba(0, 0, 0, .85);
  /* footer copy sits over the Monster wordmark, so it carries its own halo -
     declared once here rather than repeated on six selectors */
  --shadow-text-ftr: 0 1px 4px var(--nle-ink);

  /* ── scrims. A scrim is not a surface: tinting a photograph with the brand
        green turned the client's white ute olive, so these are near-black with
        only a whisper of the hue, graded per frame. ───────────────────────── */
  --hero-scrim: linear-gradient(180deg,
      rgba(9, 13, 7, .34) 0%,
      rgba(9, 13, 7, .54) 24%,
      rgba(9, 13, 7, .70) 44%,
      rgba(9, 13, 7, .82) 66%,
      rgba(9, 13, 7, .94) 100%);
  /* the footer wordmark's vertical fade, as a token so the mask carries no
     literal (the transition runs UP BEHIND the footer columns) */
  --wordmark-fade: linear-gradient(180deg,
      transparent 0%,
      rgba(9, 13, 7, .02) 48%,
      rgba(9, 13, 7, .16) 66%,
      rgba(9, 13, 7, .58) 84%,
      var(--nle-ink) 100%);
  --band-scrim: linear-gradient(180deg,
      rgba(9, 13, 7, .84) 0%,
      rgba(9, 13, 7, .74) 46%,
      rgba(9, 13, 7, .86) 100%);
  /* caption legibility over a photo tile */
  --caption-scrim: linear-gradient(180deg, transparent, rgba(9, 13, 7, .82));

  /* ══ THE KIT CONTRACT ══════════════════════════════════════════════════
     design-library/kit/tokens.template.css names these; the poetic names above
     stay and these alias onto them (rk:kit-and-skin). ─────────────────── */
  --accent-deep:  var(--brand-deep);
  --wordmark:     var(--ink-quiet);

  --deep:    var(--steel-900);
  --deep-2:  var(--steel-800);
  --deep-3:  var(--steel-700);

  --sheet:   var(--field-4);
  --paper:   #ffffff;

  --link-on-deep:  var(--accent-2);   /* analogous, 8.4:1 on --steel-900 */
  --link-on-light: var(--brand-deep); /* analogous, 6.2:1 on white */

  --rule-accent: var(--brand);
  --rule-quiet:  var(--steel-600);
  --rule-light:  var(--rule-hair);
  --fold-rule:   3px;

  /* --r-control / --r-card / --r-plate / --r-signature are declared in the
     shape block above, as real values on one derived scale rather than four
     aliases onto a single flat number. */
  --border-w:    1px;

  --font-data:       var(--font-body);
  --display-weight:  700;
  --display-track:   var(--tracking-display);
  --display-case:    uppercase;
  --h1:      var(--fs-h1);
  --h2:      var(--fs-h2);
  --h3:      var(--fs-h3);
  --body:    var(--fs-body);
  --body-lh: var(--leading-body);
  --small:   var(--fs-small);
  --btn-label: var(--fs-btn);

  --header-h:    var(--hdr-h);
  --header-h-sm: var(--hdr-h-sm);
  --sec-pad:     var(--pad-section);
  --gutter:      var(--pad-gutter);
  --card-pad:    34px;
  --control-h:   var(--ctl-h);
  --submit-h:    var(--ctl-h-lg);

  --motion-name: "detent";
  --settle:      var(--reveal);
  --reveal-rise: 18px;
  --stagger:     55ms;

  --shadow-plate:        var(--shadow-contact), var(--shadow-cast);
  --text-shadow-display: var(--shadow-text);
  --text-shadow-small:   var(--shadow-text-sm);

  --grain:       var(--texture-plate-dark);
  --grain-light: var(--texture-plate);

  --signature-name: "lockout-tag call plate";
}

@media (prefers-reduced-motion: reduce) {
  :root { --snap: 1ms linear; --snap-slow: 1ms linear; --reveal: 1ms linear;
          --glint: 1ms linear; --reveal-rise: 0px; --stagger: 0ms; }
}

@media (max-width: 900px) {
  :root { --hdr-h: var(--hdr-h-sm); --header-h: var(--hdr-h-sm); --hdr-bar-h: 68px; --hdr-inset: 18px; }
}

/* The photo bands' shared height steps UP on a phone, because the same copy
   stacks roughly a third taller there. Still one token, still one value per
   breakpoint, still matched up to the taller band - never set per section
   (rk:photo-band-parity + rk:global-rules-live-on-the-base). Declared HERE
   rather than in site.css so it cannot be overridden by source order, which is
   exactly how the first attempt at this silently did nothing. */
@media (max-width: 600px) {
  :root { --band-min-h: 700px; }
}
