/* ===========================================================================
   EVOCANDA — THE PUBLIC FACE. reddenda.org/doorknock
   ---------------------------------------------------------------------------
   Owner: @DK-HOME. Authored 2026-09-11.

   THE ONE SENTENCE THIS PAGE EXISTS TO SAY:
     Every alert system broadcasts. Ours listens.

   WHY THE DESIGN IS BUILT THIS WAY, so the next lane does not "improve" it back:

   1. ONE HUE, AND IT MEANS A PERSON. The product's token doctrine (sibling repo
      packages/ui/src/tokens.css) is that saturated colour means human safety and
      nothing else, so interface chrome carries no hue. This page obeys it. Every
      surface, rule, label and button here is neutral. The brand amber #D99A2B
      appears in exactly two roles: the one lit home in the mark, and a household
      that answered "I cannot get out alone". That is why the amber reads as
      urgent at all. The page this replaced flooded #ff6a3d through its kickers,
      headings, borders, buttons and five decorative washes, and by the time a
      reader reached a fact that mattered, orange meant nothing.

   2. NO GRADIENT BLOBS, NO GLASSMORPHISM, NO BACKDROP-FILTER. The predecessor
      carried two 52vmax circles at filter:blur(90px) animating for 46 and 52
      seconds, plus four more at blur(110px) further down. They were the single
      loudest "generated" tell on the page. Depth here comes from a real
      elevation ramp and hairlines. The sticky nav is SOLID, not frosted: it is
      cheaper to composite, it never smears type, and it is what the studios this
      is measured against actually ship.

   3. MOTION IS ARGUMENT, NOT DECORATION. There is exactly one continuous
      animation on this page and it is the hero field, because the hero field IS
      the thesis: a broadcast sweeping out and nothing coming back, then a call
      going out and answers coming home. Everything else moves once, on entry,
      to direct the eye, and then stops. Nothing here breathes, shimmers, orbits
      or pulses forever.

   4. TYPE AND SPACE ARE ON SCALES, declared once below. Nothing in this file
      sets an ad-hoc px size. The display sizes are fluid between a 390 and a
      1440 anchor so the deck reads across a room and on a phone in a truck.

   5. IBM PLEX is the brand face, from the lockup. Plex Mono carries every
      number, because a figure that changes must not reflow the line it sits in.
   =========================================================================== */

/* ---------------------------------------------------------------- TOKENS -- */
:root{
  /* --- The neutral ramp. Cool, navy-undertoned, not grey. ----------------- */
  --ev-0:#07080B;   /* below everything */
  --ev-1:#0B0C0E;   /* page ground. The brand's own near-black. */
  --ev-2:#11131A;   /* raised: cards, nav when condensed */
  --ev-3:#171A23;   /* raised higher, hover */
  --ev-4:#1F232E;   /* hairline, subtle */
  --ev-5:#2A2F3D;   /* hairline, default */
  --ev-6:#3A4152;   /* hairline, strong / disabled ink */
  --ev-7:#6B7487;   /* muted ink. 4.6:1 on --ev-1 */
  --ev-8:#9AA4B2;   /* secondary ink. 7.9:1 on --ev-1 */
  --ev-9:#C8CED9;   /* strong secondary */
  --ev-10:#E6EAF2;  /* primary ink. 15.2:1 on --ev-1 */
  --ev-11:#FFFFFF;

  /* --- Brand. Two values. That is the whole budget. ----------------------- */
  --ev-navy:#1E3A8A;      /* the mark's ink in light contexts */
  --ev-navy-lift:#4C6FD4; /* navy raised to hold AA on the dark ground */
  --ev-lit:#D99A2B;       /* THE LIT HOME. A person who cannot get out alone. */
  --ev-lit-soft:rgba(217,154,43,.13);
  --ev-lit-edge:rgba(217,154,43,.42);

  --ev-bg:var(--ev-1);
  --ev-ink:var(--ev-10);
  --ev-dim:var(--ev-8);
  --ev-mute:var(--ev-7);
  --ev-line:var(--ev-4);
  --ev-line-2:var(--ev-5);

  /* --- Type scale. 1.26 for text, 1.31 for display. Fluid 390 -> 1440. ---- */
  --t-2xs:11.5px;
  --t-xs:13px;
  --t-sm:15px;
  --t-base:17px;
  --t-md:clamp(18px,.55vw + 16px,21px);
  --t-lg:clamp(21px,1.1vw + 17px,27px);
  --t-xl:clamp(25px,1.9vw + 18px,36px);
  --t-2xl:clamp(31px,3.1vw + 19px,49px);
  --t-3xl:clamp(37px,5.0vw + 18px,67px);
  --t-4xl:clamp(43px,7.4vw + 14px,91px);

  --lh-tight:1.02;
  --lh-snug:1.12;
  --lh-head:1.2;
  --lh-body:1.55;
  --lh-loose:1.65;

  /* Optical tracking: large type needs negative, small caps need positive. */
  --tr-display:-.035em;
  --tr-head:-.022em;
  --tr-body:-.005em;
  --tr-over:.15em;

  /* --- Space scale. 4px base. -------------------------------------------- */
  --s-1:4px;  --s-2:8px;  --s-3:12px; --s-4:16px; --s-5:24px;
  --s-6:32px; --s-7:40px; --s-8:56px; --s-9:80px; --s-10:112px; --s-11:152px;
  --gut:clamp(20px,5vw,64px);          /* page gutter */
  --sec:clamp(72px,11vh,148px);        /* section rhythm */
  --measure:62ch;                      /* body measure */
  --max:1308px;                        /* content max: 1180 of content + 2 x 64 gutter,
                                        so .ev-wrap and the sections resolve to ONE
                                        left edge. They used to differ by exactly 34px
                                        at every width, which put the nav, the hero,
                                        the section headlines and the footer on three
                                        separate verticals down one page. */

  /* --- Motion. Durations on a scale, easings named for their job. --------- */
  --d-1:120ms; --d-2:180ms; --d-3:260ms; --d-4:380ms; --d-5:560ms; --d-6:900ms;
  /* Settle: fast out, long tail. Everything that ARRIVES uses this. */
  --e-settle:cubic-bezier(.22,1,.36,1);
  /* Firm: symmetric, for things that toggle between two equal states. */
  --e-firm:cubic-bezier(.65,0,.35,1);
  /* Exit: slow out, fast away. Things that LEAVE. */
  --e-exit:cubic-bezier(.4,0,1,1);

  --r-sm:8px; --r-md:12px; --r-lg:18px; --r-xl:26px; --r-full:999px;

  /* --- Elevation. Layered, never one soft black blur. -------------------- */
  --el-1:0 1px 2px rgba(0,0,0,.30), 0 0 0 1px rgba(255,255,255,.035);
  --el-2:0 2px 4px rgba(0,0,0,.26), 0 8px 20px rgba(0,0,0,.28), 0 0 0 1px rgba(255,255,255,.045);
  --el-3:0 4px 8px rgba(0,0,0,.28), 0 18px 44px rgba(0,0,0,.40), 0 0 0 1px rgba(255,255,255,.055);

  --nav-h:68px;

  /* THE BAND. The one number that decides how much of the hero the mountain owns.
     David's brief: it cuts into the LOWER part of the fold and never takes the whole
     hero. 34svh is the proportion that reads as a horizon rather than a wallpaper;
     the floor keeps the town lights alive on a short laptop and the ceiling stops a
     tall desktop turning it back into a backdrop. Everything else, the canvas size,
     the copy's bottom padding and the caption's seat, is derived from this. */
  /* ★ ONE CONTINUOUS FORMULA, AND THE REASON IS A MEASURED DISCONTINUITY.
     This was clamp(190px,31svh,306px) while a separate @media (max-height:760px) block
     changed the hero's box model underneath it, so the hero's height JUMPED 32px across the
     760/761 boundary: drag a window one pixel taller and the whole fold re-laid out.
     MEASURED on live evocanda.com at 1440: hero 733px at h=760, 765px at h=761.
     `42svh - 95px` is the same curve without the step (650 -> 178px, 700 -> 199, 760 -> 224,
     900 -> 283, 1080 -> 359) and the clamp only catches the extremes. */
  --ev-band:clamp(140px,42svh - 95px,372px);
  /* The room the Grizzly Flats ledger occupies at the FOOT of the band. The copy column
     reserves (--ev-band minus this) beneath itself, and the ledger itself supplies the rest
     by being in the flow. Splitting it this way is what lets the ledger sit visually ON the
     mountain while still being a normal flex child that can never be laid over anything. */
  --ev-cap-space:96px;
}
/* The phone gets a SHALLOWER band than the desktop in proportion, but a real one. At 23svh
   it was 194px, and after the floor took 46% of that there were 105px of mountain left,
   which is a texture rather than a ridge. 29svh is 245px at 844 and the content above it is
   budgeted to end by then. */
@media (max-width:860px){ :root{ --nav-h:60px; --ev-band:clamp(140px,38svh - 78px,262px); --ev-cap-space:84px } }

/* ------------------------------------------------------------------ RESET -- */
.ev *,.ev *::before,.ev *::after{box-sizing:border-box}
.ev [hidden]{display:none!important}

html.ev-root{
  background:var(--ev-bg);
  -webkit-text-size-adjust:100%;
  /* The nav is fixed; in-page anchors must not land under it. */
  scroll-padding-top:calc(var(--nav-h) + var(--s-5));
}
@media (prefers-reduced-motion:no-preference){ html.ev-root{scroll-behavior:smooth} }

body.ev{
  margin:0;
  background:var(--ev-bg);
  color:var(--ev-ink);
  font-family:"IBM Plex Sans",ui-sans-serif,system-ui,-apple-system,"Segoe UI",sans-serif;
  font-size:var(--t-base);
  line-height:var(--lh-body);
  letter-spacing:var(--tr-body);
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  font-synthesis-weight:none;      /* never let a browser fake a weight */
  text-rendering:optimizeLegibility;
  /* clip, not hidden. `hidden` makes this element a scroll container, which
     silently kills position:sticky anywhere inside it: the California map
     declared sticky and tracked its wrapper off the screen for 815px. `clip`
     is non-scrollable by spec, so it still prevents horizontal scrolling
     (measured: scrollWidth - clientWidth = 0) without creating that container.
     hidden stays first as the fallback for engines that do not know clip. */
  overflow-x:hidden;
  overflow-x:clip;
}
.ev img,.ev svg,.ev video,.ev canvas{max-width:100%;display:block}
.ev h1,.ev h2,.ev h3,.ev h4{font-weight:600;text-wrap:balance}
.ev p{text-wrap:pretty}

/* Every number on this page is tabular and monospaced, so a counting figure
   never shifts the words beside it. */
.ev-num{font-family:"IBM Plex Mono",ui-monospace,"SF Mono",Menlo,monospace;
  font-variant-numeric:tabular-nums;font-feature-settings:"zero" 1;letter-spacing:-.01em}

/* The overline. One rule, used everywhere a section names itself. */
.ev-over{
  font-size:var(--t-2xs);font-weight:600;letter-spacing:var(--tr-over);
  text-transform:uppercase;color:var(--ev-mute);margin:0;
  font-feature-settings:"ss02" 1;
}

/* Focus: ONE visible ring, on the page's own ink, never the brand amber.
   Amber means a person in this product and must not be spent on a focus ring. */
.ev :focus-visible{
  outline:2px solid var(--ev-10);
  outline-offset:3px;
  border-radius:var(--r-sm);
}
.ev :focus:not(:focus-visible){outline:none}

.ev-skip{
  position:fixed;top:var(--s-2);left:var(--s-2);z-index:200;
  transform:translateY(-200%);
  background:var(--ev-10);color:var(--ev-1);
  padding:var(--s-3) var(--s-4);border-radius:var(--r-sm);
  font-size:var(--t-sm);font-weight:600;text-decoration:none;
  transition:transform var(--d-2) var(--e-settle);
}
.ev-skip:focus{transform:none}

.ev-sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}

.ev-wrap{max-width:var(--max);margin-inline:auto;padding-inline:var(--gut);width:100%}

/* =========================================================== THE LOCKUP == */
/* Geometry is the canonical 64-viewBox cut, ratified by @DK-CONSOLE. The
   wordmark is LIVE TEXT, not the lockup SVG: that file carries an
   @import of a webfont, which the <img> sandbox blocks, so it falls back to
   Helvetica and its -5 tracking at 172px then reads as broken rather than as
   a different face. It also carries an opaque background rect, so it can only
   ever sit on its own colour. Live text renders correctly, stays selectable,
   stays accessible, and scales with the type scale. */
.ev-lock{display:inline-flex;align-items:center;gap:var(--lk-gap,10px);text-decoration:none;color:inherit}
.ev-lock__mark{flex:none;width:var(--lk-mark,24px);height:var(--lk-mark,24px)}
.ev-lock__text{display:flex;flex-direction:column;min-width:0}
.ev-lock__word{
  font-size:var(--lk-word,21px);font-weight:600;line-height:1;
  letter-spacing:-.028em;color:var(--ev-ink);white-space:nowrap;
}
/* The definition is subordinate at ~0.42 of the wordmark, hairline-separated,
   and OMITTED rather than shrunk below 22px. @DK-CONSOLE measured it running
   off a 390px card as "THOSE WHO MUST BE CA"; hence the clamp and the nowrap
   only above the width where it fits. */
.ev-lock__rule{display:block;height:1px;background:var(--ev-line-2);margin:var(--s-2) 0 6px;width:100%}
.ev-lock__def{
  font-size:var(--lk-def,9px);font-weight:500;line-height:1.1;
  letter-spacing:.14em;text-transform:uppercase;color:var(--ev-mute);
}
/* In the nav the lockup is identity only: mark + wordmark, no definition.
   The name is DEFINED once, prominently, in the hero, and again in the footer. */
.ev-lock--nav{--lk-mark:30px;--lk-word:20px;--lk-gap:11px}
@media (max-width:520px){
  .ev-lock--nav{--lk-mark:27px;--lk-word:18px;--lk-gap:9px}
}

/* ============================================================== THE NAV == */
.ev-nav{
  position:fixed;inset:0 0 auto 0;z-index:100;height:var(--nav-h);
  display:flex;align-items:center;
  /* SOLID, never frosted. See note 2 at the top of this file. */
  background:transparent;
  border-bottom:1px solid transparent;
  transition:background var(--d-3) var(--e-firm),
             border-color var(--d-3) var(--e-firm),
             height var(--d-3) var(--e-firm);
}
/* The bar materialises once the hero's top edge is gone, so the hero reads as
   full-bleed on arrival and the nav reads as a surface once you are reading. */
.ev-nav[data-stuck="1"]{
  background:var(--ev-1);
  border-bottom-color:var(--ev-line);
  height:calc(var(--nav-h) - 8px);
  box-shadow:0 1px 0 rgba(255,255,255,.03), 0 8px 24px rgba(0,0,0,.38);
}
.ev-nav__in{
  max-width:var(--max);margin-inline:auto;padding-inline:var(--gut);
  width:100%;display:flex;align-items:center;gap:var(--s-5);
}
.ev-nav__brand{margin-right:auto;padding:var(--s-2) 0;border-radius:var(--r-sm)}

.ev-nav__links{
  display:flex;align-items:center;gap:2px;list-style:none;margin:0;padding:0;
  position:relative;
}
.ev-nav__links a{
  display:block;padding:9px 14px;border-radius:var(--r-sm);
  font-size:var(--t-sm);font-weight:500;color:var(--ev-dim);
  text-decoration:none;white-space:nowrap;
  transition:color var(--d-2) var(--e-firm);
}
.ev-nav__links a:hover{color:var(--ev-ink)}
.ev-nav__links a[aria-current="true"]{color:var(--ev-ink)}

/* SCROLL-SPY INDICATOR. One element that TRAVELS between the links rather than
   six elements that fade. Shared-element motion: the eye tracks one object, so
   the nav tells you where you are in the page without you reading it. Animated
   on transform and width only, so it composites. */
.ev-nav__ind{
  position:absolute;bottom:-1px;left:0;height:2px;width:0;
  background:var(--ev-ink);border-radius:2px;
  opacity:0;transform:translateX(0);
  transition:transform var(--d-4) var(--e-settle),
             width var(--d-4) var(--e-settle),
             opacity var(--d-2) var(--e-firm);
  pointer-events:none;
}
.ev-nav__ind[data-on="1"]{opacity:1}

.ev-nav__act{display:flex;align-items:center;gap:var(--s-3)}

/* ----- Buttons. Two kinds. Neutral primary, hairline secondary. ----------- */
.ev-btn{
  --btn-h:46px;
  display:inline-flex;align-items:center;justify-content:center;gap:10px;
  height:var(--btn-h);padding:0 var(--s-5);border-radius:var(--r-full);
  font-family:inherit;font-size:var(--t-sm);font-weight:600;letter-spacing:-.008em;
  text-decoration:none;cursor:pointer;border:1px solid transparent;
  transition:transform var(--d-2) var(--e-settle),
             background-color var(--d-2) var(--e-firm),
             border-color var(--d-2) var(--e-firm),
             color var(--d-2) var(--e-firm),
             box-shadow var(--d-2) var(--e-firm);
  -webkit-tap-highlight-color:transparent;
}
.ev-btn:active{transform:scale(.985)}
.ev-btn svg{flex:none}

.ev-btn--primary{background:var(--ev-10);color:var(--ev-1);box-shadow:var(--el-1)}
.ev-btn--primary:hover{background:var(--ev-11);box-shadow:var(--el-2)}

.ev-btn--ghost{background:transparent;color:var(--ev-ink);border-color:var(--ev-line-2)}
.ev-btn--ghost:hover{background:var(--ev-2);border-color:var(--ev-6)}

.ev-btn--lg{--btn-h:56px;padding:0 var(--s-6);font-size:var(--t-md)}

/* QUIET. For a control that is real and pressable but must not pull the eye off the
   primary one beside it. No fill, no border, no pill: ink, a hairline underline on
   hover, and a 44px hit box it keeps whatever the type does. The hero used to carry
   its film control as .ev-btn--primary, a solid white pill, directly beside the phone
   line. Two primaries in one block is not a hierarchy, it is a coin toss. */
.ev-btn--quiet{
  --btn-h:44px;
  background:transparent;color:var(--ev-9);border-color:transparent;
  padding:0;gap:9px;font-size:var(--t-sm);
}
.ev-btn--quiet:hover{color:var(--ev-ink);background:transparent}
.ev-btn--quiet .ev-play__ico{
  width:26px;height:26px;border-radius:var(--r-full);flex:none;
  display:inline-flex;align-items:center;justify-content:center;
  border:1px solid var(--ev-line-2);color:var(--ev-ink);
  transition:border-color var(--d-2) var(--e-firm),background-color var(--d-2) var(--e-firm);
}
.ev-btn--quiet .ev-play__ico svg{width:11px;height:11px;margin-left:1px}
.ev-btn--quiet:hover .ev-play__ico{border-color:var(--ev-7);background:var(--ev-2)}
.ev-btn--quiet svg{width:14px;height:14px}
@media (max-width:420px){ .ev-btn--lg{--btn-h:52px;padding:0 var(--s-5);font-size:var(--t-base)} }

/* ----- The mobile trigger. Two bars that become a cross. ------------------ */
.ev-burger{
  display:none;width:44px;height:44px;padding:0;border:0;background:transparent;
  cursor:pointer;position:relative;border-radius:var(--r-sm);color:var(--ev-ink);
}
.ev-burger i{
  position:absolute;left:11px;width:22px;height:1.5px;background:currentColor;
  border-radius:2px;transition:transform var(--d-3) var(--e-firm),opacity var(--d-2) var(--e-firm);
}
.ev-burger i:nth-child(1){top:17px}
.ev-burger i:nth-child(2){top:25px}
.ev-burger[aria-expanded="true"] i:nth-child(1){transform:translateY(4px) rotate(45deg)}
.ev-burger[aria-expanded="true"] i:nth-child(2){transform:translateY(-4px) rotate(-45deg)}

/* ----- The sheet. A real panel: scroll-locked, focus-trapped, Escape-closed,
         with rows at 56px so a thumb in a truck cannot miss. ---------------- */
.ev-sheet{
  position:fixed;inset:0;z-index:99;background:var(--ev-1);
  display:flex;flex-direction:column;
  padding:calc(var(--nav-h) + var(--s-5)) var(--gut) calc(var(--s-7) + env(safe-area-inset-bottom));
  opacity:0;visibility:hidden;
  transition:opacity var(--d-3) var(--e-firm),visibility var(--d-3) step-end;
}
.ev-sheet[data-open="1"]{opacity:1;visibility:visible;transition:opacity var(--d-3) var(--e-firm),visibility 0s}
.ev-sheet__links{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}
.ev-sheet__links li{border-bottom:1px solid var(--ev-line)}
.ev-sheet__links a{
  display:flex;align-items:center;justify-content:space-between;
  min-height:60px;padding:var(--s-4) 0;
  font-size:var(--t-lg);font-weight:500;letter-spacing:var(--tr-head);
  color:var(--ev-ink);text-decoration:none;
}
.ev-sheet__links a span{font-size:var(--t-xs);color:var(--ev-mute);font-weight:500;letter-spacing:0}
.ev-sheet__links a:active{color:var(--ev-dim)}
.ev-sheet__foot{margin-top:auto;padding-top:var(--s-6);display:grid;gap:var(--s-3)}
.ev-sheet__foot .ev-btn{width:100%}
.ev-sheet__def{margin:var(--s-5) 0 0;font-size:var(--t-xs);color:var(--ev-mute);line-height:var(--lh-body)}
.ev-sheet__def b{color:var(--ev-dim);font-weight:600}

/* Staggered arrival. The rows travel a short distance, fast, with a long tail:
   it reads as the panel settling rather than as six separate fades. */
.ev-sheet__links li,.ev-sheet__foot{
  opacity:0;transform:translateY(10px);
}
.ev-sheet[data-open="1"] .ev-sheet__links li,
.ev-sheet[data-open="1"] .ev-sheet__foot{
  opacity:1;transform:none;
  transition:opacity var(--d-4) var(--e-settle) var(--sd,0ms),
             transform var(--d-5) var(--e-settle) var(--sd,0ms);
}

@media (max-width:860px){
  .ev-nav__links,.ev-nav__act .ev-btn--ghost{display:none}
  .ev-burger{display:block}
}
@media (min-width:861px){
  .ev-sheet{display:none}
}
/* A nav CTA at 390 would leave the wordmark 96px of room. The sheet carries it. */
@media (max-width:520px){ .ev-nav__act .ev-btn--primary{display:none} }

/* ============================================================== THE HERO == */
/* THE ARGUMENT THIS SECTION MAKES, in the order a reader receives it:
     1. the name, and what it means                (kicker + definition)
     2. the thesis, in five words                  (h1)
     3. the PROOF that the thesis is not a slogan  (the field, see evocanda-hero.js)
     4. the mechanism, in one plain sentence       (lede)
     5. one thing to do                            (a single primary action)
   A reader who stops after line 2 has the whole point. That is the five-second
   test, and it is why the h1 is the thesis rather than a scene-setter. */

/* ANCHORED, NOT CENTRED. Measured before this changed: a centred content block
   in a 100svh hero puts HALF the leftover height above the lockup, so the empty
   black at the top grew with the viewport and the scene lost the same amount at
   the bottom. Real numbers, gap from nav bottom to lockup:
       390x844 151px   430x932 190px   768x1024 201px   1920x1080 192px
   while 1440x900, the size this was designed at, sat at a correct 102px. The
   copy was drifting down and the mountain was being squeezed off the fold on
   every viewport except one.
   Anchoring to the top and letting a clamp own the gap holds 1440 where it was
   (99px) and gives every other size its 60 to 90px back AS SCENE: the town
   lights at the bottom of the band are the product, and they now have room.
   The clamp, not a fixed value, so a short laptop does not get a 132px void.
   This does NOT touch the band: .ev-scene keeps inset:0 and its mask. */
/* ★ THE HERO NOW FITS THE FOLD, AND IT DID NOT BEFORE. This rule claimed
   min-height:100svh and every reader assumed that meant "one screen". It does not: it
   is a FLOOR, and the content was overrunning it at every width. MEASURED 2026-09-11
   with the film control forced visible, which is what a browser with h264 actually
   renders:

     320  fold 844  hero 1303      390  fold 844  hero 1220
     768  fold 900  hero 1070     1440  fold 900  hero 1076     1920  fold 900  hero 1076

   So the hero was 19% to 54% taller than the screen everywhere, the phone line's bottom
   edge sat at 925px against a 900px fold, and the scene caption at 965px. The two things
   the hero exists to show were below the fold on every device.
   The fix is budgeted, not hopeful: the top padding is smaller, the band is reserved as
   padding-bottom rather than left to overlap, and the copy column is capped. */
.ev-hero{
  position:relative;isolation:isolate;
  min-height:100svh;
  display:flex;flex-direction:column;justify-content:flex-start;
  /* The bottom padding is now just the ledger's breathing room. The BAND is reserved on
     .ev-hero__in instead, because the ledger has to be able to sit inside the band while
     still being laid out after the copy. */
  padding:calc(var(--nav-h) + clamp(22px,4.4vh,58px)) 0 clamp(10px,2.2vh,24px);
  overflow:clip;
}

/* ----- The plate. Real footage of a real ridge burning, at low luminance,
         under a vertical scrim so the type never sits on moving detail. It is
         8 seconds and it loops on its own dissolve. It is NOT a gradient and it
         is NOT decoration: it is the thing the product exists for, and it is the
         only photographic element on the page. Falls back to a still poster
         under reduced-motion, on save-data, and on any decode failure. ------- */
.ev-plate{position:absolute;inset:0;z-index:-1;overflow:hidden;background:var(--ev-0)}
.ev-plate video,.ev-plate img{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  /* The footage is bright and orange; the page is not. Desaturating and
     darkening it keeps the single amber in the field as the loudest warm thing
     on screen, which is the whole colour argument. */
  filter:saturate(.55) brightness(.42) contrast(1.06);
  opacity:0;transition:opacity var(--d-6) var(--e-settle);
}
.ev-plate[data-ready="1"] video,.ev-plate[data-ready="1"] img{opacity:1}
/* Two scrims, not one: a vertical one to seat the type, and a floor to carry
   the field and the buttons. A single radial wash is the tell we are avoiding. */
.ev-plate::after{
  content:"";position:absolute;inset:0;
  background:
    linear-gradient(180deg,rgba(11,12,14,.92) 0%,rgba(11,12,14,.74) 26%,rgba(11,12,14,.80) 58%,var(--ev-1) 96%),
    linear-gradient(90deg,rgba(11,12,14,.55) 0%,transparent 34%,transparent 66%,rgba(11,12,14,.55) 100%);
}

.ev-hero__in{position:relative;z-index:1;width:100%;max-width:var(--max);
  margin-inline:auto;padding-inline:var(--gut);
  /* Reserves the mountain BENEATH the copy, minus the strip the ledger will occupy itself.
     This is what guarantees no control can ever end up sitting on the ridge, and it is a
     property of the flow rather than of a guessed offset. */
  padding-bottom:max(0px,calc(var(--ev-band) - var(--ev-cap-space)))}

/* ----- The name, defined, in five words, as part of the mark.
         David 2026-09-11: the homepage must not be wordy. So the etymology
         sentence is NOT above the fold; it is in the footer. What sits here is
         the lockup's own caption, which is five words and is identity rather
         than body copy. The name is still defined under the mark, as ordered. */
/* .ev-hero__name is GONE from the markup and its rules are deleted rather than left
   here looking load-bearing. The nav lockup is the only place the brand is rendered. */

/* ----- The thesis. Five words on three lines. ---------------------------- */
/* Two lines, not three, and deliberately NOT --t-4xl (which tops out at 91px). At 91px
   over three lines the headline alone was 278px of a 900px fold, and it was competing
   with the one control underneath it rather than introducing it. 76px over two lines is
   232px at 1440 and sets "Every alert system broadcasts." on a single line at 1440 and
   1920, which is the read the sentence was written for. max-width is in ch so the measure
   holds as the size moves. */
.ev-hero__h1{
  /* Capped by HEIGHT as well as width. A width-only clamp sets 76px on a 1440x650 laptop
     exactly as it does on a 1440x1080 desktop, and at 650 that headline alone is a third of
     the viewport, which is what forced the hero taller than the screen on every short
     window. 8.4svh: 650 -> 54.6px, 700 -> 58.8, 760 -> 63.8, 900 -> 75.6, 1080 -> 76, and it
     is inert on every phone and tablet because the width clamp is smaller there anyway. */
  margin:0;font-size:min(clamp(38px,5.6vw + 8px,76px),8.4svh);line-height:var(--lh-tight);
  letter-spacing:var(--tr-display);font-weight:600;
  max-width:22ch;text-wrap:balance;
}
/* "listens" is the only word on this page set in the lit amber, because it is
   the only word on this page that names what nothing else does. */
.ev-hero__h1 em{font-style:normal;color:var(--ev-lit)}
.ev-hero__h1 .ev-l{display:block;overflow:hidden}
.ev-hero__h1 .ev-l > span{display:block;will-change:transform}
/* Lines rise from their own clipping mask: one object arriving, not three
   fades. Stagger is 70ms, short enough to read as a single gesture. */
.ev-js .ev-hero__h1 .ev-l > span{transform:translateY(105%);
  transition:transform var(--d-6) var(--e-settle) var(--ld,0ms)}
.ev-js.ev-in .ev-hero__h1 .ev-l > span{transform:none}

/* ONE line, twelve words or fewer. It is a statement, not a paragraph, so it is
   set at display weight on a short measure and never wraps past two lines. */
.ev-hero__lede{
  margin:var(--s-4) 0 0;max-width:52ch;text-wrap:balance;
  font-size:clamp(17px,.75vw + 14px,22px);line-height:1.4;letter-spacing:var(--tr-head);
  font-weight:450;color:var(--ev-8);
}

/* ----- The actions. ONE primary. ----------------------------------------- */
/* ══ THE HERO IS TWO COLUMNS ON A WIDE SCREEN, AND THAT IS WHAT THE VOID WAS FOR. ══
   The thesis and the lede still run full width, because they are the statement. Below them
   the fold splits: the phone line on the left, the film on the right. Before this the right
   half of the hero was empty from the nav to the mountain, measured at 212px of dead black
   at 1920, while the film was a 44px text link underneath the form. */
.ev-hero__in{display:grid;grid-template-columns:1fr;align-content:start}
.ev-hero__h1,.ev-hero__lede{grid-column:1/-1}
@media (min-width:1024px){
  .ev-hero__in{
    grid-template-columns:minmax(0,1fr) minmax(360px,40%);
    column-gap:clamp(28px,3.4vw,64px);
  }
  .ev-hero__act{grid-column:1;grid-row:3}
  /* ★ .ev-hero__in SCOPES THIS BECAUSE THE BASE .ev-hero__alt RULE SITS LATER IN THIS FILE.
     At equal specificity the later rule wins even from inside a media query, so `border-top:0`
     computed as the base rule's 1px hairline and a stray rule floated above the poster at
     1440 and 1920. That is the fourth time this exact trap has bitten this stylesheet; the
     others are annotated where they happened. Scoping raises specificity, so it actually
     applies. VERIFY BY COMPUTED STYLE, never by reading the declaration. */
  /* David 2026-09-12: the film sits BELOW the call CTA, full width, unmistakable. Was column 2 beside it. */
  .ev-hero__in .ev-hero__alt{grid-column:1 / -1;grid-row:4;margin-top:clamp(18px,2.6vh,30px);
    padding-top:0;border-top:0;max-width:none;align-self:start}
}

/* ── THE FILM. A poster with a play badge and a runtime, not a text link. ──────────────
   It is a <button>, so it is keyboard reachable and announces itself, and the poster is a
   real <img> with width/height so it reserves its own aspect box and cannot shift the fold
   while it decodes. .ev-play is the class evocanda-hero.js gates on: the card ships [hidden]
   and is only revealed after the film's own metadata loads in THIS browser. */
.ev-film{
  /* ★ THE CARD IS CAPPED BY VIEWPORT HEIGHT, AND IT IS ONE CONTINUOUS FORMULA ON PURPOSE.
     A 16:9 card sized only by its column is a fixed 266px tall at 1440, which is fine at
     900px of viewport and is 35% of a 760px one. Adding it broke two things that Section 1
     of the fix spec had just established: `hero === innerHeight` failed again at 650/700/
     720/760, and the 760/761 jump came back at 26px because the short-desktop media query
     shrinks the type either side of the card while the card itself did not move.
     A media query here would reintroduce exactly that step. `(100svh - 520px) * 1.778`
     is the same curve with no boundary: 650 -> 231px wide, 760 -> 427, and from about 695
     upward the column width binds first and the cap stops mattering. 1.778 is 16/9, so the
     poster's aspect box follows it. MEASURED after: jump back under 4px, hero === innerHeight
     restored at every desktop height. */
  max-width:100%; /* the svh-driven cap moved behind a desktop query (audit 2026-09-13: it crushed the card to 178px on 700px-tall screens) */
  display:block;position:relative;width:100%;padding:0;border:0;overflow:hidden;
  border-radius:var(--r-lg);background:var(--ev-2);cursor:pointer;
  box-shadow:var(--el-2);isolation:isolate;
  transition:transform var(--d-3) var(--e-settle),box-shadow var(--d-3) var(--e-firm);
}
.ev-film[hidden]{display:block!important;visibility:hidden;pointer-events:none} /* reserve the 16:9 box: CLS 0.05 came from this reveal */
.ev-film:hover{transform:translateY(-2px);box-shadow:var(--el-3)}
.ev-film:focus-visible{outline:2px solid var(--ev-10);outline-offset:3px}
.ev-film__poster{
  display:block;width:100%;height:auto;aspect-ratio:16/9;object-fit:cover;
  /* The footage is bright and orange and the page is not. Matching the plate's own grade
     keeps the single amber in the hero the loudest warm thing on screen. */
  filter:saturate(.78) brightness(.72) contrast(1.04);
  transition:filter var(--d-4) var(--e-firm),transform var(--d-6) var(--e-settle);
}
.ev-film:hover .ev-film__poster{filter:saturate(.9) brightness(.84) contrast(1.04);transform:scale(1.012)}
.ev-film::after{
  content:"";position:absolute;inset:auto 0 0;height:58%;pointer-events:none;
  background:linear-gradient(180deg,rgba(7,8,11,0),rgba(7,8,11,.82) 72%,rgba(7,8,11,.94));
}
/* The badge. A filled disc, because an outline circle on a photograph reads as decoration. */
/* ★ SCOPED TO .ev-film ON PURPOSE. The badge also carries .ev-play__ico so the existing
   film gate keeps working, and the generic `.ev-play__ico{width:38px;height:38px}` rule sits
   LATER in this file at equal specificity, so it silently won and the badge rendered 38px
   instead of the 56 to 72 asked for here. MEASURED at both widths before this line existed.
   Third cascade collision in this file; the others are noted where they happened. */
.ev-film .ev-film__badge{
  position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);z-index:2;
  width:clamp(56px,6vw,72px);height:clamp(56px,6vw,72px);border-radius:var(--r-full);
  display:grid;place-items:center;border:0;
  background:rgba(255,255,255,.94);color:var(--ev-1);
  box-shadow:0 8px 32px -6px rgba(0,0,0,.6);
  transition:transform var(--d-3) var(--e-settle),background-color var(--d-2) var(--e-firm);
}
.ev-film .ev-film__badge svg{width:40%;height:40%;margin-left:8%}
.ev-film:hover .ev-film__badge{transform:translate(-50%,-50%) scale(1.07);background:#fff}
.ev-film .ev-play__ico{border:0}
.ev-film__bar{
  position:absolute;left:0;right:0;bottom:0;z-index:2;
  display:flex;align-items:center;justify-content:space-between;gap:var(--s-3);
  padding:var(--s-4) var(--s-4) var(--s-4) var(--s-5);text-align:left;
}
.ev-film .ev-play__txt{
  display:flex;align-items:baseline;gap:9px;flex-direction:row;
  font-size:var(--t-sm);font-weight:600;color:var(--ev-11);letter-spacing:-.008em;
}
.ev-film .ev-play__dur{
  font-family:"IBM Plex Mono",ui-monospace,monospace;font-size:var(--t-2xs);font-weight:500;
  color:rgba(255,255,255,.66);font-variant-numeric:tabular-nums;letter-spacing:.02em;
}
/* Says the word, so nothing on this page can be mistaken for the audio brief again. */
.ev-film__kind{
  flex:none;font-size:var(--t-2xs);font-weight:600;letter-spacing:var(--tr-over);
  text-transform:uppercase;color:rgba(255,255,255,.72);
  padding:4px 9px;border-radius:var(--r-full);border:1px solid rgba(255,255,255,.24);
}
.ev-hero__links{display:flex;flex-wrap:wrap;align-items:center;gap:var(--s-3) var(--s-5);margin-top:var(--s-4)}
.ev-share{--btn-h:44px}
.ev-share__t{min-width:5.5ch;text-align:left}
@media (prefers-reduced-motion:reduce){
  .ev-film,.ev-film__poster,.ev-film__badge{transition:none}
  .ev-film:hover{transform:none}
  .ev-film:hover .ev-film__poster{transform:none}
}

/* The hero holds ONE control block and it is the phone line. */
.ev-hero__act{display:block;margin-top:clamp(18px,2.6vh,30px)}
/* and one quiet row of secondaries under it, separated by a hairline rather than by
   another band of whitespace, so the fold does not pay twice for the same gap. */
.ev-hero__alt{
  display:flex;flex-wrap:wrap;align-items:center;gap:var(--s-6);
  margin-top:clamp(14px,1.9vh,22px);padding-top:clamp(12px,1.7vh,18px);
  border-top:1px solid var(--ev-line);max-width:620px;
}
.ev-hero__note{margin:var(--s-4) 0 0;font-size:var(--t-xs);color:var(--ev-mute);max-width:40ch}

/* The play affordance. It exists in the DOM but is [hidden] until a HEAD on the
   film itself returns 200 with a video content-type. See evocanda-hero.js.
   On 2026-08-05 this estate shipped a homepage play button whose guard HEADed
   the POSTER while the mp4 was gitignored, so production served a control that
   could not play. The guard here checks the exact byte stream it will play. */
.ev-play{--btn-h:56px;padding-inline:var(--s-3) var(--s-6);gap:var(--s-3)}
.ev-play__ico{
  width:38px;height:38px;border-radius:var(--r-full);flex:none;
  display:grid;place-items:center;background:var(--ev-1);color:var(--ev-10);
  transition:transform var(--d-3) var(--e-settle);
}
.ev-play:hover .ev-play__ico{transform:scale(1.06)}
.ev-play__ico svg{width:14px;height:14px;margin-left:2px}
.ev-play__txt{display:flex;flex-direction:column;align-items:flex-start;line-height:1.25;text-align:left}
.ev-play__txt small{font-size:var(--t-2xs);font-weight:500;opacity:.62;letter-spacing:.01em}

/* =============================================== THE FIELD (the proof) === */
/* 1,687 marks. One for every distinct street address in Grizzly Flats,
   El Dorado County, counted from the county's own public parcel records.
   Positions are schematic and the page says so. The COUNT is measured. */
.ev-field{
  margin-top:var(--s-7);
  border:1px solid var(--ev-line);border-radius:var(--r-lg);
  background:linear-gradient(180deg,rgba(17,19,26,.72),rgba(11,12,14,.86));
  box-shadow:var(--el-2);
  overflow:hidden;
}
.ev-field__head{
  display:flex;align-items:baseline;gap:var(--s-4);flex-wrap:wrap;
  padding:var(--s-4) var(--s-5) var(--s-3);border-bottom:1px solid var(--ev-line);
}
.ev-field__act{
  margin-left:auto;display:flex;align-items:center;gap:var(--s-2);
  font-size:var(--t-2xs);font-weight:600;letter-spacing:var(--tr-over);
  text-transform:uppercase;color:var(--ev-mute);
  background:transparent;border:1px solid var(--ev-line-2);border-radius:var(--r-full);
  padding:7px 13px;cursor:pointer;font-family:inherit;
  transition:color var(--d-2) var(--e-firm),border-color var(--d-2) var(--e-firm);
}
.ev-field__act:hover{color:var(--ev-ink);border-color:var(--ev-6)}
.ev-field__act svg{width:12px;height:12px}

/* The caption is the act label: it is what the motion MEANS, and it changes
   with the motion. Crossfaded, never re-laid-out, so the box never jumps. */
.ev-field__cap{
  position:relative;min-height:1.9em;padding:var(--s-3) var(--s-5) 0;
}
.ev-field__cap p{
  position:absolute;inset:var(--s-3) var(--s-5) auto;margin:0;
  font-size:var(--t-sm);line-height:1.4;color:var(--ev-dim);max-width:52ch;
  opacity:0;transform:translateY(4px);
  transition:opacity var(--d-4) var(--e-firm),transform var(--d-4) var(--e-settle);
}
.ev-field__cap p[data-on="1"]{opacity:1;transform:none}
.ev-field__cap b{color:var(--ev-ink);font-weight:600}
.ev-field__cap .ev-lit{color:var(--ev-lit)}

.ev-field__canvas{display:block;width:100%;height:auto}

/* The ledger. Three cells that state what the field is showing, in numbers.
   Mono, tabular, so a counting figure cannot reflow its own label. */
.ev-ledger{
  display:grid;grid-template-columns:repeat(3,1fr);
  border-top:1px solid var(--ev-line);
}
.ev-ledger div{padding:var(--s-4) var(--s-5);border-left:1px solid var(--ev-line)}
.ev-ledger div:first-child{border-left:0}
.ev-ledger dt{
  margin:0 0 6px;font-size:var(--t-2xs);font-weight:600;letter-spacing:var(--tr-over);
  text-transform:uppercase;color:var(--ev-mute);
}
.ev-ledger dd{
  margin:0;font-size:var(--t-xl);font-weight:600;line-height:1;
  letter-spacing:-.025em;color:var(--ev-ink);
}
.ev-ledger dd small{display:block;margin-top:7px;font-size:var(--t-2xs);font-weight:500;
  letter-spacing:0;color:var(--ev-mute);line-height:1.4;font-family:"IBM Plex Sans",sans-serif}
/* The only coloured cell in the ledger, and it is a person. */
.ev-ledger div[data-lit="1"] dd{color:var(--ev-lit)}
.ev-ledger div[data-lit="1"]{background:var(--ev-lit-soft);box-shadow:inset 0 1px 0 var(--ev-lit-edge)}

/* A cell that has no honest number yet renders a dash and says why. It never
   renders a zero, because a zero is a measurement and a dash is an absence. */
.ev-ledger dd[data-empty="1"]{color:var(--ev-6)}

.ev-field__src{
  padding:var(--s-3) var(--s-5) var(--s-4);border-top:1px solid var(--ev-line);
  font-size:var(--t-2xs);color:var(--ev-mute);line-height:1.5;
}
.ev-field__src a{color:var(--ev-dim);text-decoration:none;border-bottom:1px solid var(--ev-6)}
.ev-field__src a:hover{color:var(--ev-ink);border-bottom-color:var(--ev-8)}

@media (max-width:700px){
  .ev-ledger{grid-template-columns:1fr 1fr}
  .ev-ledger div:nth-child(3){grid-column:1/-1;border-left:0;border-top:1px solid var(--ev-line)}
  .ev-field__head{padding-inline:var(--s-4)}
  .ev-field__cap{padding-inline:var(--s-4)}
  .ev-field__cap p{inset:var(--s-3) var(--s-4) auto}
  .ev-ledger div,.ev-field__src{padding-inline:var(--s-4)}
}
@media (max-width:420px){
  .ev-ledger{grid-template-columns:1fr}
  .ev-ledger div{border-left:0;border-top:1px solid var(--ev-line)}
  .ev-ledger div:first-child{border-top:0}
  .ev-ledger div:nth-child(3){border-top:1px solid var(--ev-line)}
}

/* Short-viewport hero: a laptop at 1200x700 and a phone at 390x640 must still
   show the thesis AND the primary action without scrolling. The field is the
   thing that yields, because the h1 carries the argument on its own. */
/* ── SHORT DESKTOP (861+ wide, 760 or less tall: a laptop with a Dock or a taskbar). ──
   TYPE AND GAPS YIELD HERE. THE BOX MODEL DOES NOT. This block has now broken the hero
   twice by reaching for the box model instead:
     v1 set `padding-bottom:var(--s-7)` (40px) while .ev-scene stayed bottom-anchored at
        var(--ev-band) (190px+), so the band rose up to 196px into the copy column and the
        Grizzly Flats ledger was painted across "Watch the film" and "Open the live demo".
        MEASURED at 1280x720: hero 563px, .ev-hero__alt 465-523, .ev-scenecap 468-547.
     v2 kept `min-height:0`, which makes the hero exactly content-tall and produced a 32px
        step across the 760/761 boundary. MEASURED at 1440: 733px at 760, 765px at 761.
   THE INVARIANT: the space the band occupies is reserved as padding that the copy column
   cannot enter, and nothing in a media query may take that reservation away. Shrink the
   type, tighten the gaps, drop the ledger below 600px tall. Never the padding, never the
   min-height. */
/* ★ THIS MEDIA QUERY IS GONE AND ITS JOB IS DONE BY CONTINUOUS CLAMPS INSTEAD.
   It stepped padding-top, three margins and the lede's font-size at exactly 760px tall, and
   a step is a visible re-layout: measured, the hero jumped 16 to 27px when the window grew
   by ONE pixel across that boundary. The base rules it was overriding are already written as
   clamps on vh/svh, so they yield smoothly on their own and the override was only ever
   re-flattening them into a discontinuity.
   THIS BLOCK HAS NOW BROKEN THE HERO THREE TIMES: padding-bottom:var(--s-7) let the mountain
   rise into the copy and put the ledger over the CTAs; min-height:0 caused the first jump;
   the type and gap steps caused this one. Do not reintroduce it. If a short window needs to
   yield, widen a clamp. */
@media (max-height:760px) and (min-width:861px){
  .ev-field{margin-top:var(--s-5)}
}
}
/* Under 600px tall the ledger is the thing that goes, not the controls. */
@media (max-height:600px) and (min-width:861px){ .ev-scenecap{display:none} }
}
@media (max-height:680px) and (max-width:860px){
  /* 390x640. The thesis, the line and the one button must clear the fold, so the
     lockup caption yields: the mark still identifies, the name is defined in the
     footer, and nothing that carries the argument is lost. */
  .ev-hero{min-height:0}
  .ev-hero__name .ev-lock__rule,.ev-hero__name .ev-lock__def{display:none}
  .ev-hero__name{margin-bottom:var(--s-5)}
}

/* ------------------------------------------------- REDUCED MOTION ------- */
/* Measured, not asserted. Every animated property declared in this file is
   named here, and the entrance transforms are reset to their ARRIVED state so
   that nothing is left invisible. A reveal animation that is the only thing
   which would have shown an element is a content-hiding bug under reduce, and
   it is the most common way this media query is got wrong. */
@media (prefers-reduced-motion:reduce){
  html.ev-root{scroll-behavior:auto}
  .ev *,.ev *::before,.ev *::after{
    animation-duration:1ms!important;animation-iteration-count:1!important;
    transition-duration:1ms!important;transition-delay:0ms!important;
  }
  .ev-js .ev-hero__h1 .ev-l > span{transform:none!important}
  .ev-sheet__links li,.ev-sheet__foot{opacity:1!important;transform:none!important}
  .ev-plate video{display:none}      /* the still poster carries it instead */
  .ev-plate[data-ready="1"] img{opacity:1}
  .ev-field__cap p[data-on="1"]{opacity:1;transform:none}
}

/* ====================================================== LOCK + THEATRE == */
/* Scroll lock for the sheet and the theatre. overflow:hidden on the root, not
   position:fixed on the body: the fixed-body trick scrolls the page to the top
   the moment it is applied and then back, which on a phone reads as a flicker. */
html.ev-locked,html.ev-locked body{overflow:hidden}

.ev-theatre{
  padding:0;border:0;background:transparent;max-width:none;max-height:none;
  width:100%;height:100%;
}
.ev-theatre::backdrop{background:rgba(5,6,8,.92)}
.ev-theatre__in{
  position:fixed;inset:0;display:grid;place-items:center;
  padding:clamp(12px,3vw,44px);
}
.ev-theatre__frame{
  position:relative;width:100%;max-width:1360px;aspect-ratio:16/9;
  background:#000;border-radius:var(--r-md);overflow:hidden;box-shadow:var(--el-3);
}
.ev-theatre video{width:100%;height:100%;object-fit:contain;background:#000}
.ev-theatre__x{
  position:absolute;top:calc(12px + env(safe-area-inset-top));right:12px;
  width:44px;height:44px;border-radius:var(--r-full);border:1px solid var(--ev-line-2);
  background:var(--ev-1);color:var(--ev-ink);cursor:pointer;
  display:grid;place-items:center;
  transition:background var(--d-2) var(--e-firm),border-color var(--d-2) var(--e-firm);
}
.ev-theatre__x:hover{background:var(--ev-3);border-color:var(--ev-6)}
.ev-theatre__x svg{width:16px;height:16px}
@media (min-width:900px){ .ev-theatre__x{top:24px;right:24px} }

/* The indicator's carrier. A <ul> may only contain <li>, so the travelling
   underline lives in a presentational, zero-width list item and resolves its
   absolute position against the <ul>, which is the relative ancestor. */
.ev-nav__indwrap{width:0;height:0;overflow:visible;pointer-events:none}

/* ======================================================= THE NAME, DEFINED */
/* David's order: the mark everywhere, and DEFINE the name under it. The hero
   carries the five-word caption; this is where the etymology is stated, once,
   at the foot of the page, where a reader who wants it will look for it. */
.ev-name{border-top:1px solid var(--ev-line);padding:var(--s-9) 0}
.ev-name__in{display:flex;align-items:center;gap:clamp(20px,3vw,40px)}
.ev-name__mark{flex:none;width:clamp(52px,7vw,76px);height:clamp(52px,7vw,76px);color:var(--ev-dim)}
.ev-name__h{margin:0;font-size:var(--t-2xl);letter-spacing:var(--tr-display);line-height:1}
.ev-name__p{margin:var(--s-3) 0 0;max-width:44ch;font-size:var(--t-md);color:var(--ev-dim);line-height:1.45}
.ev-name__p b{color:var(--ev-ink);font-weight:600}
.ev-name__p i{font-style:italic;color:var(--ev-9)}
@media (max-width:520px){ .ev-name{padding:var(--s-8) 0} .ev-name__in{gap:var(--s-4)} }

/* ======================================================= THE CALL CONTROL */
/* David 2026-09-11: a WORKING calling demo lives in the hero. A visitor types
   their own number, taps once, and the Evocanda voice calls them and asks the
   one question. This is the product, performed on the reader, and it is the
   most persuasive thing on the page.

   THE MARKUP CONTRACT IS NOT MINE TO INVENT. /doorknock/call-button.js is the
   working implementation and it queries #dk-call, #dk-call-btn (with a
   .dk-call-label inside), #dk-call-num, #dk-call-name, #dk-call-consent,
   #dk-call-status, plus the .dk-call-row / .dk-call-consent / .dk-call-kicker
   class hooks it toggles between its three honest states. Those ids and classes
   are load-bearing. This file restyles them and changes nothing about them.

   WHY THERE IS NO PARAGRAPH OF LEGAL TEXT. The old card carried a three-sentence
   disclaimer above the fold. The duties are real (47 CFR 64.1200(b), FCC 24-17
   on AI voice, and all-party recording consent in CA/WA/MT/NV), but they are
   discharged by the CONSENT LABEL, which the visitor must actively tick, and by
   the call's own spoken opener. A checkbox nobody reads is worse compliance than
   one sentence they must tick to proceed. */
/* ── THE LINE ──────────────────────────────────────────────────────────────────────────
   WHAT CHANGED 2026-09-11 (@DK-HOME): this block used to target .dk-call-kicker,
   .dk-call-row, .dk-call-in, .dk-call-btn and .dk-call-consent. The BEM rewrite renamed
   every one of them in the markup, so the whole block was DEAD and had been for as long
   as the new hero existed; the component was actually being styled by a second, raw-hex
   copy inlined in index.html that used none of these tokens. Rewritten against the class
   names that are really in the DOM, so there is one implementation again.

   IT IS NOT A CARD ANY MORE, AND THAT IS THE WHOLE POINT. Boxed, on --ev-2 with --el-2 and
   an 18px radius, it read as a widget dropped onto the mountain: measured at 1440 it was a
   620x268 panel floating over the ridge with its bottom edge at 925px, below a 900px fold.
   A hairline, a row and a scale is what Vercel and Linear actually ship, and it lets the
   hero read as one column of type that ends in a control rather than as copy plus a gadget.

   THE LABELS ARE STILL THERE, THEY ARE JUST NOT DRAWN. Two uppercase micro-labels above two
   inputs cost 24px of the fold and told a visitor what a placeholder already says. They are
   now visually hidden, which keeps the <label> association a screen reader needs and removes
   the chrome a sighted reader does not.

   NO PARAGRAPH OF LEGAL TEXT, deliberately. The duties are real (47 CFR 64.1200(b), FCC
   24-17 on AI voice, all-party recording consent in CA/WA/MT/NV) and they are discharged by
   the CONSENT LABEL, which must be actively ticked, and by the call's own spoken opener. A
   checkbox nobody reads is worse compliance than one sentence they must tick to proceed. */
.ev-call{
  margin:0;width:100%;max-width:620px;
  display:flex;flex-direction:column;align-items:flex-start;gap:var(--s-3);
}
/* ★ EVERY PART call-button.js TOGGLES NEEDS ITS OWN [hidden] RULE, AND THIS IS NOT DEFENSIVE
   PADDING. `hidden` is styled by ONE rule in the UA stylesheet, [hidden]{display:none}, and
   ANY author rule beats the UA origin. So `.ev-call__consent{display:flex}` below silently
   wins over it, and setting el.hidden=true on that element leaves it on screen. Without these
   lines invite mode cannot hide the number field it is not allowed to offer, and Book a call
   ships visible on a form that is meant to be dialling. Same class of defect as a media query
   that loses on cascade order: the rule shipped, and changed nothing. */
.ev-call[hidden],
.ev-call__field[hidden],.ev-call__row[hidden],
.ev-call__consent[hidden],.ev-call__book[hidden]{display:none!important}

/* The overline. call-button.js rewrites its text per state, so it is never a static label. */
.ev-call__lede{
  margin:0;font-size:var(--t-2xs);font-weight:600;letter-spacing:var(--tr-over);
  text-transform:uppercase;color:var(--ev-dim);
}

.ev-call__row{display:flex;gap:var(--s-2);align-items:stretch;flex-wrap:wrap;width:100%}
.ev-call__field{flex:1 1 140px;min-width:0;display:block}
/* THE NAME FIELD IS NOT DRAWN, AND THE INPUT STAYS IN THE FORM. call-button.js reads
   nameEl.value either way and the server accepts an empty name: PROVEN end to end on
   2026-09-11 by submitting a number with the name blank and getting "Ringing." back.
   So the second input bought nothing and cost a decision plus, on a phone where the row
   stacks, 64px of the fold. One input and one button is the whole control now.
   display:none rather than removing the element, because removing it would mean editing
   another lane's JS contract for a layout reason. */
.ev-call__field:not(.ev-call__field--num){display:none}
.ev-call__field--num{flex:1 1 200px}
/* Visually hidden, not display:none: display:none removes it from the accessibility tree
   too, and then the input has no accessible name at all. */
.ev-call__label{
  position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip-path:inset(50%);white-space:nowrap;border:0;
}
.ev-call input[type=text],.ev-call input[type=tel]{
  width:100%;height:54px;padding:0 var(--s-4);
  border-radius:var(--r-md);border:1px solid var(--ev-6);
  background:var(--ev-1);color:var(--ev-ink);
  font-family:"IBM Plex Mono",ui-monospace,monospace;
  font-size:var(--t-base);font-variant-numeric:tabular-nums;letter-spacing:.02em;
  transition:border-color var(--d-2) var(--e-firm),background-color var(--d-2) var(--e-firm);
}
.ev-call input::placeholder{color:var(--ev-7);font-family:"IBM Plex Sans",sans-serif;letter-spacing:0}
.ev-call input[type=text]:hover,.ev-call input[type=tel]:hover{border-color:var(--ev-8)}
.ev-call input[type=text]:focus,.ev-call input[type=tel]:focus{
  outline:2px solid var(--ev-10);outline-offset:2px;border-color:var(--ev-8);background:var(--ev-2);
}

.ev-call__go{
  flex:0 0 auto;height:54px;padding:0 var(--s-5);border:0;border-radius:var(--r-md);
  background:var(--ev-10);color:var(--ev-1);cursor:pointer;
  font-family:inherit;font-size:var(--t-sm);font-weight:600;letter-spacing:-.008em;
  display:inline-flex;align-items:center;justify-content:center;white-space:nowrap;
  transition:background-color var(--d-2) var(--e-firm),transform var(--d-2) var(--e-settle);
}
.ev-call__go:hover{background:var(--ev-11)}
.ev-call__go:active{transform:scale(.985)}
.ev-call__go:focus-visible{outline:2px solid var(--ev-10);outline-offset:3px}
.ev-call__go[aria-disabled="true"]{cursor:progress;background:var(--ev-9)}
/* Invite mode puts a whole sentence on this button ("Book a call. We ring you on it.") and
   it is then the only control in the row, so it takes the full width instead of running off
   the edge. This is the state the live line is in whenever budget_ok is false, which it was
   on prod on 2026-09-11, so it is not a rare branch. */
.ev-call__row:has(.ev-call__field[hidden]) .ev-call__go{flex:1 1 100%}

/* 44px of hit box around a 20px control, because the label is the target too. The native
   checkbox this replaced measured 13x13 and failed every touch guideline on the page. */
.ev-call__consent{
  display:flex;align-items:flex-start;gap:10px;cursor:pointer;
  margin:0;padding:var(--s-2) 0;min-height:44px;
  font-size:var(--t-xs);line-height:1.45;color:var(--ev-dim);max-width:58ch;
}
.ev-call__consent input{
  appearance:none;-webkit-appearance:none;margin:0;flex:none;
  width:20px;height:20px;border-radius:6px;
  border:1.5px solid var(--ev-6);background:var(--ev-1);
  display:grid;place-content:center;cursor:pointer;
  transition:background-color var(--d-1) var(--e-firm),border-color var(--d-1) var(--e-firm);
}
.ev-call__consent input::before{
  content:"";width:10px;height:6px;
  border-left:2px solid var(--ev-1);border-bottom:2px solid var(--ev-1);
  transform:rotate(-45deg) translate(1px,-1px);opacity:0;
}
.ev-call__consent input:checked{background:var(--ev-10);border-color:var(--ev-10)}
.ev-call__consent input:checked::before{opacity:1}
.ev-call__consent input:focus-visible{outline:2px solid var(--ev-10);outline-offset:2px}

/* Status and the booking escape sit on ONE row. Stacked they were two 20px rows plus a
   12px gap at the very bottom of the fold, for two pieces of small print that are read in
   the same glance. */
.ev-call__foot{display:flex;flex-wrap:wrap;align-items:baseline;gap:var(--s-2) var(--s-4);width:100%}
.ev-call__status{margin:0;font-size:var(--t-xs);line-height:1.45;color:var(--ev-mute);min-height:1.45em;flex:1 1 240px}
/* An error is the one other thing allowed to carry a hue, and it is NOT the brand amber:
   amber on this page means a household, and a failed dial is not a household. */
.ev-call__status.is-err{color:#E8756A}
.ev-call__book{
  margin:0;font-size:var(--t-xs);color:var(--ev-mute);text-decoration:none;
  align-self:flex-start;border-bottom:1px solid var(--ev-6);
}
.ev-call__book b{color:var(--ev-dim);font-weight:600}
.ev-call__book:hover,.ev-call__book:hover b{color:var(--ev-ink)}
.ev-call__hp{position:absolute!important;left:-9999px;width:1px;height:1px;opacity:0}

/* ★ 380, NOT 560. The row stacked below 560px, which put the number and the button on two
   lines at 390 and 430 and cost 64px of an 844px fold, and that 64px was the difference
   between the mountain band opening inside the first screen and opening below it. MEASURED
   at 390: inner width 350, the input holds its 200px minimum, "Call me now" needs 143, and
   the 8px gap fits with a pixel to spare. Below 380 the input would shrink past its
   placeholder and it stacks instead. */
@media (max-width:379px){
  .ev-call__row{gap:10px}
  .ev-call__field--num{flex:1 1 100%}
  .ev-call__go{flex:1 1 100%}
}
/* 390x700 and shorter: the line is the fold's last inch, so it loses its overline rather
   than its consent line. The consent line is a legal duty. */
@media (max-height:700px) and (max-width:860px){
  .ev-call{gap:var(--s-2)}
  .ev-call__lede{display:none}
}

/* The demo link's arrow leans out of the button on hover, the way a link that
   leaves the page should. Transform only, so it composites. */
.ev-demo svg{width:15px;height:15px;transition:transform var(--d-2) var(--e-settle)}
.ev-demo:hover svg{transform:translate(2px,-2px)}
@media (prefers-reduced-motion:reduce){ .ev-demo:hover svg{transform:none} }

/* TWO STACKED BUTTONS MUST BE ONE BLOCK, NOT TWO SHAPES.
   Measured on the live page at 320/360/390/430: the play control came out
   209x56 and the demo control 223x52, stacked and left-aligned. Two buttons of
   different width AND different height sitting on top of each other is the
   detail that reads as assembled rather than designed, and it is invisible to
   every assertion because nothing overflows and nothing is clipped. Below the
   width where they sit side by side they now share one full-width column and
   one height. The .ev-play override is why the heights diverged: ev-btn--lg
   drops to 52px under 420px and .ev-play was pinning 56. */
/* ONE HEIGHT FOR BOTH QUIET CONTROLS. .ev-play pins --btn-h:56px for the pill form it used
   to have, and .ev-btn--quiet asks for 44. Measured after the first rebuild: play 618-674
   (56px) beside demo 624-668 (44px), so two text controls on the same row sat on two
   different baselines. Twelve pixels, invisible to every assertion, and exactly the kind of
   detail that reads as assembled rather than designed. The quiet variant wins inside the
   hero's secondary row, and it has to be said here because .ev-play's own rule is later in
   the file and equally specific. */
.ev-hero__alt .ev-play{--btn-h:44px;padding-inline:0;gap:9px}
.ev-hero__alt .ev-play__txt{flex-direction:row;align-items:baseline;gap:8px}
.ev-hero__alt .ev-play__txt small{opacity:.52}

/* Under 640 the two secondaries stack, and stacked they must be one block: one column,
   one height, one left edge. The predecessor shipped 209x56 over 223x52. */
@media (max-width:639px){
  /* They are text controls now, not pills, so they fit one row on a phone and only wrap on
     a 320. Stacking them unconditionally cost 56px of a 844px fold and pushed the band's
     top edge off the bottom of the screen, which is the one thing the band must never do. */
  .ev-hero__alt{display:flex;flex-wrap:wrap;gap:var(--s-3) var(--s-5);max-width:none}
  .ev-hero__alt .ev-btn{justify-content:flex-start}
}

/* ★ 320 IS A REAL DEVICE AND IT GETS ITS OWN HEADLINE SIZE.
   At the clamp's 38px floor the thesis sets as FOUR lines in a 280px measure ("Every alert"
   / "system" / "broadcasts." / "Ours listens.") and costs 155px. MEASURED at 320x844: that
   pushed the band's top edge to y=780, leaving 64px of a 245px mountain inside the fold,
   against 215px at 390 and 279px at 1440. 31px sets the same sentence in three lines.
   ⚠️ AN EARLIER VERSION OF THIS RULE SHIPPED AND DID NOTHING. It was written as a patch to
   an `@media (max-width:359px)` block that this same pass had already deleted, so the edit
   was a silent no-op and the measurement came back byte-identical at all five widths. That
   identical-numbers signature is the only reason it was caught. If you change this rule,
   re-measure 320 and confirm the number MOVED. */
@media (max-width:359px){
  .ev-hero__h1{font-size:31px}
  .ev-hero__lede{font-size:16px}
  .ev-hero__alt{gap:var(--s-3)}
}

/* THE TWO-MINUTE CUT. A quiet footer link, not a second call to action: the
   six-minute film is the hero's, and this is for a reader who reached the
   bottom and wants the short version. It is [hidden] in the markup and only
   revealed once its own bytes decode, so before @DK-VIDEO lands the file there
   is no link rather than a dead one. */
.ev-shortwrap{border-top:1px solid var(--ev-line)}
.ev-shortwrap:not(:has(.ev-short:not([hidden]))){border-top:0}
/* ⚠️ THE GUTTER IS THE WRAPPER'S JOB, NOT THIS ELEMENT'S. The first version set
   max-width + margin-inline:auto on this anchor, which is display:inline-flex,
   and margin:auto does not centre an inline-level box. So it never centred: it
   simply took padding from x=0 and sat LEFT of everything else on any viewport
   wider than --max. MEASURED against the headline's left edge: aligned at 390,
   100px out at 1440, 340px out at 1920. Invisible at the widths people usually
   test, and glaring on the screen a VC opens it on. It lives in .ev-wrap now
   like every other block, and carries vertical padding only. */
.ev-short{
  display:inline-flex;align-items:center;gap:10px;
  padding:var(--s-6) 0;
  font-size:var(--t-sm);font-weight:500;color:var(--ev-dim);text-decoration:none;
  transition:color var(--d-2) var(--e-firm);
}
.ev-short:hover{color:var(--ev-ink)}
.ev-short svg{
  width:22px;height:22px;padding:6px;flex:none;border-radius:var(--r-full);
  border:1px solid var(--ev-line-2);box-sizing:content-box;
  transition:border-color var(--d-2) var(--e-firm),background-color var(--d-2) var(--e-firm);
}
.ev-short:hover svg{border-color:var(--ev-6);background:var(--ev-2)}
.ev-short__dur{color:var(--ev-mute);font-variant-numeric:tabular-nums}
.ev-short__dur:not(:empty)::before{content:" · "}

/* ============================================== THE SCENE (full bleed) === */
/* Grizzly Flats at night with the Caldor Fire on the crest, drawn to canvas by
   evocanda-scene.js. It sits BEHIND the copy and both controls, full bleed, and
   the fire's glow is allowed to reach up into the headline band because that is
   the thing David asked for: the fire flowing down into the hero.

   The scene draws its own top scrim, cropped to the headline band, so the type
   is legible over it. This block adds the page-side half of that contract: the
   hero's own ground colour underneath, so there is never a flash of nothing
   before the first frame composites, and a floor fade into the section below. */
.ev-hero{background:var(--ev-0)}
/* ── THE BAND. THE MOUNTAIN OWNS THE LOWER PART OF THE FOLD AND NOTHING ELSE. ─────────
   David's brief through the president, verbatim in intent: the flame mountain cuts only
   into the lower part of the hero, it never takes the whole hero, and the top stays
   premium black and white.

   WHY THE PREVIOUS TWO ATTEMPTS FAILED, so this is not undone a third time:
   (1) A HEIGHT BAND ON .ev-scene ALONE DOES NOTHING. assets/evocanda-scene.js writes
       c.style.height from JS, and an inline style outranks this sheet. Measured at 1440
       on 2026-09-11: wrapper 306px, canvas element still 900px. object-fit and
       object-position cannot rescue it either, because the canvas box already equals its
       intrinsic backing store, so there is no overflow to crop and both properties compute
       exactly as written and change nothing on screen.
   (2) A MASK ALONE DOES NOT EITHER. The ridges are drawn at 0.455 to 0.905 of the canvas
       height, so a full-height canvas puts the crest at the MIDDLE of the screen with 45%
       of empty night sky above it. Fading that in from the top keeps the empty sky and
       still paints a mountain across the headline; softening the gradient just made the
       glow bleed further up behind the type.
   THE FIX IS IN BOTH FILES AT ONCE. .ev-scene is bottom-anchored at a real height here,
   and evocanda-scene.js now measures ITS OWN WRAPPER instead of the whole section, so the
   canvas backing store is the band and the ridges land inside it. The hero reserves the
   same height as padding-bottom, so copy never sits on the mountain at any width.
   The mask that remains is a SHORT top feather, 0 to 14%, to seat the band's sky against
   the black above it. It is a seam, not a wash. */
.ev-scene{
  position:absolute;left:0;right:0;bottom:0;top:auto;
  height:var(--ev-band);z-index:0;pointer-events:none;overflow:hidden;
  opacity:1;
  /* A SEAM, NOT A WASH, and a short one. The first version faded to solid at 20% of the
     band, which is 49px on a phone; with the floor taking another 113px off the bottom of a
     245px band there were 83px of mountain left between them and the scene rendered as a
     dark strip with a glow in it. 12% is the shortest fade that still hides the canvas's
     own top edge. */
  -webkit-mask-image:linear-gradient(to bottom,transparent 0%,rgba(0,0,0,.6) 5%,#000 12%);
  mask-image:linear-gradient(to bottom,transparent 0%,rgba(0,0,0,.6) 5%,#000 12%);
  transform:translateY(12px);animation:evSceneRise 1.6s cubic-bezier(.16,1,.3,1) .3s forwards}
.ev-scene canvas{display:block;width:100%;height:100%}
.ev-hero__in{position:relative;z-index:2}
/* A floor that carries the mountain into the page rather than cutting it off. */
/* A floor that carries the band into the section below rather than cutting it off. It is
   scaled to the BAND now, not to 22% of the whole hero: against a full-height hero that
   was 237px at 1440 and swallowed the town lights, which are the best thing in the scene
   and the only part of it that is literally the product. */
/* THE FLOOR. It does two jobs and it is sized for the harder one. It carries the band into
   the section below, and it is the ground the scene caption is read against. The caption
   measures y=816 to 871 inside a band that ends at 900, and it sits directly on the row of
   town lights, which are the brightest thing in the scene. At .34 of the band the floor was
   95px and had not darkened enough by 816 to hold the type. .46 reaches it. */
.ev-hero::after{
  content:"";position:absolute;left:0;right:0;bottom:0;z-index:1;
  height:calc(var(--ev-band) * .38);pointer-events:none;
  /* Reaches darkness FASTER over a SHORTER run, so the caption still has solid ground under
     it while the mountain above keeps the height a .46 floor was taking from it. */
  background:linear-gradient(180deg,rgba(11,12,14,0) 0%,rgba(11,12,14,.34) 26%,rgba(11,12,14,.88) 68%,var(--ev-1) 100%);
}

/* ------------------------------------------------- THE SCENE CAPTION --- */
/* The two measured facts, ON the scene. Not a chart: a label, the way a plate in
   a book is labelled. Left-aligned under the controls, hairline-ruled, and it
   never competes with the headline for the eye. */
/* ★ THE LEDGER IS A FLEX CHILD AGAIN, AND ABSOLUTE POSITIONING HERE WAS A REAL BUG I SHIPPED.
   It was moved to `position:absolute; bottom:clamp(10px,2.2vh,24px)` so it would sit on the
   band without costing the fold anything. It does not cost the fold anything. It also
   RESERVES NO SPACE, so the moment the hero was shorter than its own content the pinned
   ledger was painted straight over the controls above it.
   MEASURED on live evocanda.com at 1280x720: the `max-height:760px` rule below set
   min-height:0 AND replaced padding-bottom:var(--ev-band) with var(--s-7), the hero
   collapsed to 563px, .ev-hero__alt spanned 465-523 and the ledger 468-547.
   FIFTY-FIVE PIXELS OF OVERLAP, directly across "Watch the film" and "Open the live demo".
   David hit it on a large screen simply by not having the window at full height. One of the
   eight geometries I now check collided; seven looked perfect, which is exactly why this
   survived a five-width review.
   In the flow with `margin-top:auto` it does both jobs: free space collapses above it so it
   still sits at the foot of the hero when there is room, and when there is not it pushes the
   hero taller instead of landing on top of something. It cannot overlap a sibling it is laid
   out after. Do not put it back. */
.ev-scenecap{
  position:relative;z-index:2;
  margin:auto 0 0;padding:0 var(--gut);
  width:100%;max-width:var(--max);margin-inline:auto;
  display:flex;justify-content:flex-start;
  pointer-events:none;
}
.ev-scenecap figcaption{
  position:relative;isolation:isolate;
  display:inline-flex;flex-direction:column;gap:7px;
  padding:var(--s-3) var(--s-6) var(--s-3) var(--s-4);
  border-left:1px solid var(--ev-line-2);
}
/* NO LOCAL BOX BEHIND THE CAPTION EITHER. A one-sided gradient seats the type but it has
   to START somewhere, and that start is a hard vertical edge against a valley full of house
   lights: at 1440 it drew a visible slab from x=131 to x=560. Legibility comes from the
   hero's own FLOOR instead, which is full bleed and therefore has no edge to see. */
.ev-scenecap__place{
  font-size:var(--t-2xs);font-weight:600;letter-spacing:var(--tr-over);
  text-transform:uppercase;color:var(--ev-mute);
}
.ev-scenecap__facts{
  display:flex;align-items:baseline;gap:9px;flex-wrap:wrap;
  font-size:var(--t-sm);color:var(--ev-dim);
}
.ev-scenecap__facts b{font-size:var(--t-lg);font-weight:600;color:var(--ev-ink);line-height:1}
/* The separator is a rule, not a bullet character: a middot between two figures
   reads as a decimal point at a glance, and these are counts. */
.ev-scenecap__facts i{
  width:1px;height:1em;background:var(--ev-line-2);display:inline-block;
  margin-inline:var(--s-2);transform:translateY(.1em);
}
@media (max-width:520px){
  .ev-scenecap{margin-top:var(--s-6)}
  .ev-scenecap__facts{font-size:var(--t-xs);gap:7px}
  .ev-scenecap__facts b{font-size:var(--t-md)}
}
/* On a short phone the band is the last inch of the fold and the caption would sit on top
   of the town lights with nowhere to go. It is evidence, not chrome, and it is repeated in
   full in the section below, so it goes rather than crowds. */
@media (max-height:700px) and (max-width:860px){ .ev-scenecap{display:none} :root{--ev-cap-space:0px} }

/* THE CAPTION'S OWN LOCAL SCRIM IS GONE, BECAUSE IT BECAME A GREY RECTANGLE.
   It was a radial wash on the FIGURE, and the figure was content-width in the flow. Now
   that the figure is stretched edge to edge across the band, the same rule painted a
   560px-wide slab with a hard right edge sitting in the middle of the valley: visible at
   1440 and unmissable at 1920. Nothing needs to replace it. The hero's own floor gradient
   (.ev-hero::after, z-index 1) already darkens the bottom of the band, the caption sits
   above it at z-index 2. */
/* ONE LOCAL SCRIM, AND IT IS ON THE FIGCAPTION, NOT THE FIGURE. The figure is stretched
   edge to edge across the band now, so the wash that used to live on it painted a 560px
   slab with a hard right edge in the middle of the valley, visible at 1440 and unmissable
   at 1920. The figcaption is content width, so the same gradient seats exactly the type it
   is for and fades out before it reaches anything else. Without it "GRIZZLY FLATS, EL
   DORADO COUNTY" is measurably unreadable: it sits at y=816 to 871, which is precisely the
   row of town lights, and those lights are the brightest thing in the band. */

/* THE PHONE'S EXTRA WASH OVER THE FIRE IS DELETED, AND THE REASON IT EXISTED IS GONE.
   It dimmed the top of the hero because at 390 the crest used to sit directly behind
   "broadcasts." and "listens." and a narrow frame pushes the fire inboard. The crest is
   not behind the headline any more; it is in a band 700px below it, under type that is
   nowhere near it. What the wash was doing instead was laying rgba(11,12,14,.50) over the
   top of the band, while .ev-hero::after laid a floor over the bottom of the same band, so
   a 194px mountain on a phone was being darkened from both ends and rendered as an empty
   grey strip. Looked at, at 390, which is the only way this kind of defect is ever found. */


/* ================================================================ FOUNDERS */
/* Charlotte Engel and David Hitchman, co-founders.

   TWO THINGS WERE WRONG WITH THE FIRST VERSION AND BOTH WERE INVISIBLE TO
   ASSERTIONS. It was inserted inside .ev-shortwrap, which carries no gutter
   because the short link supplies its own padding, so the names rendered flush
   against x=0, touching the browser edge, while every other element on the page
   sat at the gutter. Measured at 1440: name left edge 0px against the Evocanda
   block's 281px. And it was styled in raw values, 15px / 11.5px / 28px / .08
   alpha, none of which are on this page's type or space scale, which is the
   "spacing eyeballed rather than systematic" tell the whole design was built to
   avoid. It is one column with everything else now, and every value below is a
   token.

   The names are a LIST, because that is what they are: two people, not two rows
   of a layout. A screen reader now says "list, 2 items". */
.ev-founders{
  list-style:none;margin:0;padding:var(--s-6) 0;
  display:grid;gap:var(--s-3);
  border-top:1px solid var(--ev-line);
}
.ev-founders li{display:flex;align-items:baseline;gap:var(--s-4);min-width:0}
.ev-founders__name{
  font-size:var(--t-base);font-weight:600;letter-spacing:var(--tr-body);
  color:var(--ev-ink);
}
/* Subordinate, and tracked the way every other overline on this page is tracked,
   so it reads as the same kind of label rather than a one-off. */
.ev-founders__role{
  font-size:var(--t-2xs);font-weight:600;letter-spacing:var(--tr-over);
  text-transform:uppercase;color:var(--ev-mute);white-space:nowrap;
}
@media (max-width:420px){
  .ev-founders{padding:var(--s-5) 0;gap:var(--s-2)}
  .ev-founders li{gap:var(--s-3)}
}

@keyframes evSceneRise{to{transform:translateY(0)}}
@media (prefers-reduced-motion:reduce){.ev-scene{animation:none;transform:none}}
/* Phones: same idea, not a shorter clip. The copy block is taller relative to
   the viewport here, so the mountain is pushed further down by the mask and held
   a little quieter, rather than cut off at 30% which shows sky and nothing else.
   Brightness follows the president's .88. */
@media (max-width:640px){.ev-scene{opacity:.88;
  -webkit-mask-image:linear-gradient(to bottom,transparent 0%,rgba(0,0,0,.06) 40%,rgba(0,0,0,.42) 62%,rgba(0,0,0,.86) 82%,#000 100%);
  mask-image:linear-gradient(to bottom,transparent 0%,rgba(0,0,0,.06) 40%,rgba(0,0,0,.42) 62%,rgba(0,0,0,.86) 82%,#000 100%)}}


/* ── THE LINE THAT FOLLOWS A DISPLAY LINE ────────────────────────────────────
   Used once, under "Every call was a recording. None could hear the answer.",
   for Lahaina. It has to be clearly subordinate to the 44px display line above
   it and clearly louder than the 14px timeline beneath it, or the reader treats
   it as a caption and skips the strongest single proof on the page. Sits at
   about 0.55 of the display line, on the ink colour, with the source chip on
   its own baseline so the sentence is never broken by a pill mid-clause. */
.st-after{
  font-size:clamp(16px,1.55vw,20px);line-height:1.5;font-weight:500;
  letter-spacing:-.005em;color:var(--st-dim,#98a3b3);
  max-width:56ch;margin:18px 0 0;text-wrap:pretty;
}
.st-after b{color:var(--st-ink,#eef2f7);font-weight:650}
.st-after .st-src{margin-left:10px;vertical-align:1px}
@media (max-width:640px){ .st-after .st-src{display:flex;margin:10px 0 0;width:max-content} }

/* 2026-09-12 (president): film poster below the CTA, wide and obvious, never a thumbnail beside a form */
.ev-hero__alt .ev-film{width:min(100%,640px)}
@media (min-width:861px){.ev-hero__in{grid-template-columns:minmax(0,1fr)} .ev-hero__act{max-width:880px} .ev-hero__in .ev-hero__alt{margin-top:clamp(14px,2vh,22px)}}

/* audit 2026-09-13 */
@media (min-width:861px) and (min-height:700px){.ev-film{max-width:min(100%,clamp(320px,calc((100svh - 600px) * 1.778),640px))}}
.ev-film__bar{white-space:nowrap}.ev-play__txt{overflow:hidden;text-overflow:ellipsis}
.ev-short,.ev-short__dur{white-space:nowrap}
