/* Kaulike Productions - shared site stylesheet.
   Lifted verbatim out of index.html so the service pages inherit the same
   design system instead of forking a second one. It was inlined on every
   homepage load before; as a file it is fetched once and cached across pages.
   Edit here, not in a page's <style>. */

  :root{
    --basalt:#EDF2F6;     /* cool paper — the sea, drained of depth */
    --basalt-2:#E2EAF2;
    --panel:#FBFDFE;
    --panel-2:#DEE8F1;
    --fog:#141C25;        /* blue-black ink, not warm black */
    --fog-dim:#47586A;
    --field:#4E6B42;      /* moss / instrument green, inked for light */
    --field-dim:#5A6A50;
    --signal:#45A0E8;     /* hi-vis flare blue -- for dark grounds and accents */
    --signal-ink:#2E6B9B; /* the same hue, dark enough to be TEXT on paper */
    --line:rgba(10,32,56,0.20);
    --line-2:rgba(10,32,56,0.11);
    --disp:'Bricolage Grotesque',system-ui,sans-serif;
    --body:'Instrument Sans',system-ui,sans-serif;
    --mono:'Space Mono',ui-monospace,monospace;
  }

  /* one notch up on the whole type scale; every size on the site is rem-based */
  html{font-size:106.25%}   /* 17px base */
  *{box-sizing:border-box;margin:0;padding:0}
  /* The page is light, but four islands stay cinematic dark: the hero (it IS
     footage), the three floating overlays, and the work cards (photography
     under a dark scrim). Each re-declares the dark tokens locally, so every
     token-driven rule inside them keeps working unchanged. */
  .hero,.work-track .card{
    --basalt:#0F1210;--basalt-2:#12160F;--panel:#161A15;--panel-2:#1C211B;
    --fog:#E7E4DA;--fog-dim:#969C8C;--field:#738767;--field-dim:#48553F;
    --line:rgba(231,228,218,0.13);--line-2:rgba(231,228,218,0.07);
    color:var(--fog)}
  html{scroll-behavior:smooth}
  /* the full-bleed bands are sized in vw, which counts the scrollbar; clip
     contains the overhang without breaking sticky the way hidden would */
  body{overflow-x:clip}
  body{
    background:
      linear-gradient(180deg,rgba(6,26,46,.20) 0,rgba(6,26,46,.07) 180px,rgba(6,26,46,0) 420px),
      var(--basalt);
    background-repeat:no-repeat;
    background-attachment:scroll;
    color:var(--fog);
    font-family:var(--body);
    line-height:1.5;
    -webkit-font-smoothing:antialiased;
    overflow-x:hidden;
  }
  ::selection{background:var(--signal);color:var(--basalt)}
  a{color:inherit;text-decoration:none}
  img{display:block;max-width:100%}

  /* grain overlay across whole page */
  body::after{
    content:"";position:fixed;inset:0;z-index:9;pointer-events:none;
    opacity:.05;mix-blend-mode:overlay;
    background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  }

  .mono{font-family:var(--mono);font-size:0.6875rem;letter-spacing:.16em;text-transform:uppercase}


  /* ---------- top bar ---------- */
  /* The lens clicker owns the hero's right flank on desktop; the paragraph
     must never run underneath it, whatever the viewport. 553px = the lens's
     clamp width + its right offset + breathing room. */
  @media(min-width:861px){ .hero:not(.no-lens) .hero-inner .sub{max-width:min(64ch,calc(100vw - 620px - clamp(24px,4vw,54px)))} }
  /* Deep-sea bar. This replaces the old mix-blend-mode:difference trick --
     the blend inverted whatever footage was behind it (and would have
     inverted a background colour too), so with a real bar the contrast is
     guaranteed and the blend is no longer needed. */
  header{
    position:fixed;top:0;left:0;right:0;z-index:30;
    display:flex;align-items:center;justify-content:space-between;
    padding:22px clamp(24px,4vw,54px);
    color:#F6EAF2;
    -webkit-backdrop-filter:blur(10px) saturate(1.1);backdrop-filter:blur(10px) saturate(1.1);
    border-bottom:1px solid rgba(200,170,200,.24);
    box-shadow:0 8px 26px rgba(8,8,14,.5),inset 0 1px 0 rgba(235,215,235,.07);
  }
  /* The leather itself: one grained layer that drifts around the whole hue
     wheel, so the bar breathes through magenta, ember, moss, teal and back.
     Slow on purpose -- it should read as light moving on material, not RGB
     gamer trim. Text and icons sit above, untouched by the filter. */
  header::before{content:"";position:absolute;inset:0;pointer-events:none;
    background:
      url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.055'/%3E%3C/svg%3E"),
      linear-gradient(180deg,rgba(52,15,42,.95) 0%,rgba(36,10,29,.9) 62%,rgba(24,7,20,.74) 100%);
    animation:leatherDrift 36s linear infinite}
  header>*{position:relative}
  /* Real light on the leather: a tiny 116KB leak loop screened over the
     drifting layer. The blend keeps blacks invisible, so only the flare
     lands; text sits above it. */
  .hdr-leak{position:absolute!important;inset:0;width:100%;height:100%;object-fit:cover;
    mix-blend-mode:screen;opacity:.5;pointer-events:none}
  @media (prefers-reduced-motion:reduce){.hdr-leak{display:none}}
  @keyframes leatherDrift{to{filter:hue-rotate(360deg)}}
  @media (prefers-reduced-motion:reduce){header::before{animation:none}}
  /* keyboard skip link: off-screen until focused, then drops into view */
  .skip-link{position:fixed;left:12px;top:-60px;z-index:200;background:var(--panel-2);color:var(--fog);
    padding:10px 16px;border:1px solid var(--signal);font-family:var(--mono);font-size:.6875rem;
    letter-spacing:.12em;text-transform:uppercase;text-decoration:none;transition:top .18s ease}
  .skip-link:focus{top:12px;outline:2px solid var(--signal);outline-offset:2px}
  /* The wordmark was Space Mono at .22em -- a terminal readout, not a name.
     It is set in the display face now, with the surname carried by weight and
     tracking rather than by another line of code-looking caps. The monospace
     stays where it belongs: the REC strip, timecodes, frame numbers. */
  .wordmark{display:flex;gap:11px;align-items:center;text-decoration:none}
  .wm-txt{display:flex;align-items:baseline;gap:.44em;font-family:var(--disp);
    text-transform:uppercase;line-height:1;white-space:nowrap}
  .wm-txt b{font-weight:800;font-size:0.9375rem;letter-spacing:.02em;color:#F4F9FD}
  .wm-txt i{font-style:normal;font-weight:400;font-size:0.75rem;letter-spacing:.2em;
    color:#9FC2DC;position:relative;padding-left:.62em}
  /* a hairline between the two words, the way a masthead rules its subtitle */
  .wm-txt i::before{content:"";position:absolute;left:0;top:50%;width:1px;height:1em;
    margin-top:-.5em;background:rgba(160,205,240,.42)}
  .wordmark:hover .wm-txt i{color:#CFE2F0}
  .wordmark:hover .wm-txt b{color:#fff}
  .wm-txt b,.wm-txt i{transition:color .2s ease}
  .wordmark .dot{width:7px;height:7px;background:var(--signal);border-radius:50%;mix-blend-mode:normal}
  /* mobile: the brand lens logo replaces the wordmark text; tapping it does a
     quick mechanical shutter-twist (class re-armed by JS) on the way home */
  .wm-logo{display:none;width:34px;height:34px}
  .wm-logo.zap{animation:logoZap .55s cubic-bezier(.34,.7,.3,1)}
  @keyframes logoZap{0%{transform:rotate(0) scale(1);filter:none}
    35%{transform:rotate(72deg) scale(.84);filter:brightness(1.7) drop-shadow(0 0 10px rgba(255,255,255,.55))}
    70%{transform:rotate(48deg) scale(1.06);filter:brightness(1.15)}
    100%{transform:rotate(60deg) scale(1);filter:none}}
  @media (max-width:860px){.wordmark .wm-txt{display:none}.wm-logo{display:block}}
  nav{display:flex;gap:26px;align-items:center}
  nav a{font-family:var(--mono);font-weight:700;font-size:0.6875rem;letter-spacing:.16em;
    text-transform:uppercase;opacity:.9;transition:opacity .2s,color .2s}
  nav a:hover{opacity:1}
  .nav-book{color:#FF9BD3!important;mix-blend-mode:normal}
  /* mail as an icon chip; the address itself lives in the tooltip, the aria
     label, and the footer link */
  /* always lit: warm glow at rest, breathing gently; hover only brightens */
  .nav-mail{width:38px;height:38px;display:grid;place-items:center;flex:none;
    color:#FFDFF1;border:1px solid rgba(255,155,211,.5);border-radius:8px;
    background:rgba(255,120,200,.09);
    box-shadow:0 0 12px rgba(255,120,200,.4),inset 0 0 8px rgba(255,150,210,.14);
    animation:mailGlow 3.2s ease-in-out infinite;
    margin-left:4px;transition:color .2s ease,border-color .2s ease,background .2s ease}
  .nav-mail svg{filter:drop-shadow(0 0 5px rgba(255,150,210,.75))}
  @keyframes mailGlow{
    0%,100%{box-shadow:0 0 10px rgba(255,120,200,.35),inset 0 0 8px rgba(255,150,210,.12)}
    50%{box-shadow:0 0 18px rgba(255,120,200,.6),inset 0 0 10px rgba(255,150,210,.2)}}
  @media (prefers-reduced-motion:reduce){.nav-mail{animation:none}}
  .nav-mail{position:relative}
  .nav-mail svg{width:17px;height:17px;display:block}
  .nav-mail .nm-share{display:none}
  @media(max-width:860px){
    .nav-mail.can-share .nm-mail{display:none}
    .nav-mail.can-share .nm-share{display:block}
  }
  /* the copied pip: a small dark chip that drops from the button and fades */
  .nm-tip{position:absolute;top:calc(100% + 10px);right:-4px;z-index:60;
    white-space:nowrap;font-family:var(--mono);font-size:0.625rem;letter-spacing:.06em;
    text-transform:none;   /* nav's uppercase would shout an address back at you */
    color:#FFE3F3;background:#2A0E22;border:1px solid rgba(255,155,211,.42);border-radius:7px;
    padding:8px 12px;opacity:0;transform:translateY(-4px);
    transition:opacity .25s ease,transform .25s ease}
  .nm-tip{pointer-events:none}
  .nm-tip.on{opacity:1;transform:translateY(0);pointer-events:auto;user-select:text}
  .nav-mail:hover{color:#fff;border-color:#FF9BD3;background:rgba(255,120,200,.16)}

  /* Phones: the bar sits over moving video with far less width to work with,
     so the ground goes nearly solid and the labels run at full strength --
     at .85 over a bright frame they washed out to unreadable. */
  @media(max-width:860px){
    header{border-bottom-color:rgba(200,170,200,.3);
      box-shadow:0 8px 26px rgba(8,8,14,.62)}
    header::before{background:
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.055'/%3E%3C/svg%3E"),
        linear-gradient(180deg,rgba(52,15,42,.985) 0%,rgba(38,11,31,.97) 60%,rgba(26,8,21,.94) 100%)}
    nav a{opacity:1;color:#FBF2F7}
    .nav-book{color:#FF9BD3!important}
  }

  /* Touch devices (iOS Safari): fixed elements using mix-blend-mode force
     per-frame recompositing against scrolling content, which makes scrolling
     stutter/jump. Drop the blends here — desktop keeps them. */
  @media (hover:none){
    body::after{display:none}
    header{mix-blend-mode:normal}
  }

  /* lacquered black band closing off the hero — gloss highlight up top, deep
     inner shadow below, and a slow specular sweep across it */
  .hero-bar{position:relative;overflow:hidden;height:18px;
    background:linear-gradient(180deg,#31352f 0%,#12150f 34%,#050605 72%,#1a1e18 100%);
    border-top:1px solid rgba(255,255,255,.09);border-bottom:1px solid rgba(0,0,0,.85);
    box-shadow:inset 0 -8px 14px rgba(0,0,0,.66),0 6px 18px rgba(0,0,0,.5)}

  /* Light bokeh over the hero: soft out-of-focus highlights drifting up and
     across, blended as light so they read as lens flare rather than dots. */
  .bokeh{position:absolute;inset:0;z-index:3;pointer-events:none;overflow:hidden;mix-blend-mode:screen}
  .bokeh span{position:absolute;bottom:-16%;border-radius:50%;opacity:0;
    background:radial-gradient(circle at 38% 34%,rgba(255,246,225,.62),rgba(255,214,150,.24) 42%,rgba(255,190,120,.06) 66%,transparent 72%);
    animation:bokehDrift linear infinite;will-change:transform,opacity}
  @keyframes bokehDrift{
    0%{transform:translate3d(0,0,0) scale(.9);opacity:0}
    12%{opacity:.5}
    62%{opacity:.32}
    100%{transform:translate3d(var(--bx,20px),-128svh,0) scale(1.12);opacity:0}
  }
  .bokeh span:nth-child(1){width:64px;height:64px;left:6%;--bx:-21px;animation-duration:34s;animation-delay:0s;filter:blur(2px)}
  .bokeh span:nth-child(2){width:38px;height:38px;left:17%;--bx:28px;animation-duration:26s;animation-delay:-6s;filter:blur(1px)}
  .bokeh span:nth-child(3){width:96px;height:96px;left:29%;--bx:-35px;animation-duration:44s;animation-delay:-13s;filter:blur(3px)}
  .bokeh span:nth-child(4){width:26px;height:26px;left:41%;--bx:42px;animation-duration:22s;animation-delay:-3s;filter:blur(1px)}
  .bokeh span:nth-child(5){width:72px;height:72px;left:53%;--bx:-49px;animation-duration:38s;animation-delay:-19s;filter:blur(2px)}
  .bokeh span:nth-child(6){width:46px;height:46px;left:64%;--bx:16px;animation-duration:30s;animation-delay:-9s;filter:blur(2px)}
  .bokeh span:nth-child(7){width:110px;height:110px;left:74%;--bx:-23px;animation-duration:52s;animation-delay:-24s;filter:blur(3px)}
  .bokeh span:nth-child(8){width:32px;height:32px;left:84%;--bx:30px;animation-duration:24s;animation-delay:-15s;filter:blur(1px)}
  .bokeh span:nth-child(9){width:58px;height:58px;left:92%;--bx:-37px;animation-duration:36s;animation-delay:-5s;filter:blur(2px)}
  .bokeh span:nth-child(10){width:84px;height:84px;left:12%;--bx:44px;animation-duration:46s;animation-delay:-30s;filter:blur(3px)}
  .bokeh span:nth-child(11){width:42px;height:42px;left:37%;--bx:-51px;animation-duration:28s;animation-delay:-21s;filter:blur(2px)}
  .bokeh span:nth-child(12){width:120px;height:120px;left:60%;--bx:18px;animation-duration:58s;animation-delay:-11s;filter:blur(3px)}
  .bokeh span:nth-child(13){width:30px;height:30px;left:70%;--bx:-25px;animation-duration:20s;animation-delay:-17s;filter:blur(1px)}
  .bokeh span:nth-child(14){width:52px;height:52px;left:47%;--bx:32px;animation-duration:32s;animation-delay:-27s;filter:blur(2px)}
  @media (prefers-reduced-motion:reduce){.bokeh{display:none}}
  /* the reviews CTA drops below the work gallery on phones, centred */
  .reviews-cta-mobile{display:flex;justify-content:center;flex-wrap:wrap;gap:10px;margin-top:20px}
  .reviews-cta-mobile{gap:18px}
  /* Bottom scrim: darkens the lower hero so the description, CTAs and the
     lens clicker stay readable over bright footage. */
  .hero-scrim{position:absolute;left:0;right:0;bottom:0;height:62%;z-index:2;pointer-events:none;
    background:linear-gradient(180deg,rgba(8,10,8,0) 0%,rgba(8,10,8,.30) 38%,rgba(8,10,8,.62) 70%,rgba(8,10,8,.82) 100%)}
  /* ---------- hero / viewfinder ---------- */
  /* min-height (not height): if a visitor has a larger accessibility text size,
     the hero grows to fit instead of spilling into the HUD and clipping the CTA. */
  .hero{position:relative;min-height:max(100svh,640px);overflow:hidden;display:flex;align-items:flex-end;
    padding-top:132px}
  /* Kill switch: the shutter toy is hidden, not deleted. Remove this class
     from the section to bring the whole mechanism back. */
  .hero.no-lens .aperture,.hero.no-lens .ap-hint{display:none!important}
  .hero.no-lens .lens-slot{display:none}
  @media (max-width:860px){.hero.no-lens .cam-stack{margin-top:0;margin-bottom:0}}
  .footage{
    position:absolute;inset:0;z-index:0;
    background:
      radial-gradient(120% 90% at 72% 18%, rgba(255,120,60,.16), transparent 55%),
      radial-gradient(140% 120% at 20% 90%, rgba(70,110,120,.28), transparent 60%),
      linear-gradient(180deg,#0b1512 0%, #14201b 40%, #0d1210 100%);
    animation:drift 26s ease-in-out infinite alternate;
  }
  .footage-vid{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;pointer-events:none;filter:brightness(.52) contrast(1.06) saturate(1.05);
    transition:opacity 1s ease}
  .footage-vid.off{opacity:0}
  .footage::before{ /* topo contour texture */
    content:"";position:absolute;inset:-10%;opacity:.18;
    background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='800' height='600' viewBox='0 0 800 600'%3E%3Cg fill='none' stroke='%236C8060' stroke-width='1' stroke-opacity='0.35'%3E%3Cpath d='M-50 120 C 150 60 300 180 500 120 S 750 60 900 130'/%3E%3Cpath d='M-50 190 C 160 140 320 250 520 190 S 760 140 900 200'/%3E%3Cpath d='M-50 270 C 170 220 330 330 540 270 S 770 220 900 280'/%3E%3Cpath d='M-50 350 C 180 300 340 410 560 350 S 780 300 900 360'/%3E%3Cpath d='M-50 430 C 190 380 350 490 580 430 S 790 380 900 440'/%3E%3Cpath d='M-50 510 C 200 460 360 570 600 510 S 800 460 900 520'/%3E%3C/g%3E%3C/svg%3E");
    background-size:cover;
  }
  @keyframes drift{from{transform:scale(1.06) translate(-1%, -1%)}to{transform:scale(1.14) translate(2%, 1.5%)}}
  .scan{position:absolute;inset:0;z-index:1;pointer-events:none;
    background:linear-gradient(rgba(255,255,255,.02) 1px, transparent 1px);background-size:100% 3px;opacity:.5}
  .vig{position:absolute;inset:0;z-index:2;pointer-events:none;
    background:radial-gradient(120% 100% at 50% 40%, transparent 55%, rgba(0,0,0,.55) 100%)}

  /* HUD readouts */
  .hud{position:absolute;inset:0;z-index:4;pointer-events:none;color:var(--fog)}
  .hud .cell{position:absolute;font-family:var(--mono);font-size:0.6875rem;letter-spacing:.12em;text-transform:uppercase;opacity:.9;display:flex;gap:8px;align-items:center}
  .hud .rec{top:96px;left:clamp(24px,4vw,54px)}
  .hud .rec .rd{width:9px;height:9px;border-radius:50%;background:#E5484D;animation:blink 1.2s steps(1) infinite}
  @keyframes blink{50%{opacity:.15}}
  .hud .tc{top:96px;right:clamp(24px,4vw,54px);color:var(--field)}
  .hud .lens{bottom:34px;left:clamp(24px,4vw,54px);color:var(--field-dim)}
  /* Each number sits in a fixed-height window and rolls like an odometer wheel:
     up when the value climbs, down when it drops. Widths are set in JS to the
     widest value each field can hold, so the separators never shuffle. */
  .lv{white-space:pre}
  .lv-sep{opacity:.55}
  .lv-n{position:relative;display:inline-block;overflow:hidden;height:1.25em;
    vertical-align:-.3em;text-align:right;font-variant-numeric:tabular-nums}
  .lv-d{position:absolute;left:0;right:0;top:0;line-height:1.25em;
    transition:transform .5s cubic-bezier(.33,1,.68,1)}
  @media (prefers-reduced-motion:reduce){.lv-d{transition:none}}
  .hud .geo{bottom:34px;right:clamp(24px,4vw,54px);text-align:right;color:var(--field-dim)}

  .hero-inner{position:relative;z-index:6;width:100%;padding:0 clamp(24px,4vw,54px) clamp(48px,7svh,96px)}
  /* The lens readout is pinned to the hero floor, so at the widths where it is
     actually painted the hero content has to clear it -- at the base padding the
     CTA row and the readout overlapped. Flat value, not a viewport-scaled one:
     the readout does not move with viewport height, so the clearance must not
     either, or the gap balloons on tall screens. Gap lands at ~20px (the CTA row
     sits 50px above the hero floor at this padding, the readout top at 51px).
     Must come after the shorthand above: a media query adds no specificity, so
     source order is what settles it. */
  @media (min-width:861px){
    .hero-inner{padding-bottom:70px}
  }
  .eyebrow{color:var(--signal);margin-bottom:22px}
  h1.hl{
    font-family:var(--disp);font-weight:800;
    font-size:clamp(2.6rem,8.2vw,7.2rem);
    line-height:.94;letter-spacing:-.02em;text-transform:uppercase;
    max-width:16ch;
  }
  h1.hl em{font-style:normal;
    background-image:linear-gradient(105deg,#4FA3E8 0%,#4FA3E8 40%,#BFE3FF 50%,#4FA3E8 60%,#4FA3E8 100%);
    background-size:240% 100%;-webkit-background-clip:text;background-clip:text;color:transparent;
    animation:priceGlint 7s ease-in-out infinite 1.2s}
  /* Each line is its own block so JS can scale the narrower one until both
     lines end flush (transform-origin:left keeps them left-aligned). */
  h1.hl .hl-l{display:block;width:-moz-fit-content;width:fit-content;transform-origin:left center;will-change:transform}
  /* depth: a hairline top light, a tight contact shadow, then two soft casts */
  /* Depth without a halo: a hairline top light and a tight contact shadow
     only. Wide blurs pooled into a dark slab here, and the animating
     clip-path cropped that pool to a hard-edged rectangle. */
  h1.hl{background:transparent;text-shadow:
    0 1px 0 rgba(255,255,255,.20),
    0 2px 2px rgba(0,0,0,.5),
    0 3px 5px rgba(0,0,0,.28)}
  h1.hl .hl-l{background:transparent}
  /* The headline and its description sweep in together behind a motion blur,
     hold while you read, then sweep back out and repeat. Both share one
     timeline so they always move as a pair. */
  .hero.open .hl{animation:heroWipeTitle 26s cubic-bezier(.2,.8,.2,1) infinite;will-change:clip-path,filter,transform}
  .hero.open .sub{animation:heroWipeSub 26s cubic-bezier(.2,.8,.2,1) infinite;will-change:clip-path,filter,transform}
  /* Both share one 15s clock. While the copy is held on screen it keeps
     drifting -- the title easing left, the description easing right -- so the
     hero is never truly static. */
  @keyframes heroWipeTitle{
    0%{clip-path:inset(0 100% 0 0);filter:blur(16px);transform:translateX(-34px);opacity:0}
    3%{clip-path:inset(0 0 0 0);filter:blur(0);transform:translateX(0);opacity:1}
    88%{clip-path:inset(0 0 0 0);filter:blur(0);transform:translateX(-6px);opacity:1}
    95%{clip-path:inset(0 0 0 100%);filter:blur(16px);transform:translateX(-30px);opacity:0}
    100%{clip-path:inset(0 0 0 100%);filter:blur(16px);transform:translateX(-30px);opacity:0}
  }
  @keyframes heroWipeSub{
    0%{clip-path:inset(0 100% 0 0);filter:blur(16px);transform:translateX(-34px);opacity:0}
    3%{clip-path:inset(0 0 0 0);filter:blur(0);transform:translateX(0);opacity:1}
    88%{clip-path:inset(0 0 0 0);filter:blur(0);transform:translateX(6px);opacity:1}
    95%{clip-path:inset(0 0 0 100%);filter:blur(16px);transform:translateX(34px);opacity:0}
    100%{clip-path:inset(0 0 0 100%);filter:blur(16px);transform:translateX(34px);opacity:0}
  }
  @media (prefers-reduced-motion:reduce){.hero.open .hl,.hero.open .sub{animation:none}}
  /* The old paragraph said five things in a row; the slate says them as a
     camera report -- label, value, hairline, next. */
  .sub{margin-top:26px;max-width:64ch;color:var(--fog-dim)}
  .hero-slate{display:flex;flex-direction:column}
  .hs-row{display:flex;align-items:baseline;gap:16px;padding:9px 0;
    border-top:1px solid rgba(231,228,218,.14)}
  .hs-row:first-child{border-top:0;padding-top:0}
  .hs-k{flex:none;width:5.2ch;font-family:var(--mono);font-size:.5625rem;font-weight:700;
    letter-spacing:.24em;text-transform:uppercase;color:#8CCCFF;
    text-shadow:0 1px 6px rgba(2,10,20,.8)}
  .hs-v{font-family:var(--mono);font-size:clamp(.78rem,1.1vw,.92rem);line-height:1.55;
    color:#D8E4EE;text-shadow:0 1px 8px rgba(2,10,20,.75)}
  .cta-row{margin-top:34px;display:flex;gap:14px;flex-wrap:wrap;pointer-events:auto}
  .btn{
    font-family:var(--mono);font-size:0.75rem;letter-spacing:.14em;text-transform:uppercase;
    padding:15px 22px;border:1px solid var(--line);color:var(--fog);
    display:inline-flex;align-items:center;gap:10px;cursor:pointer;background:transparent;
    transition:.22s ease;
  }
  .btn:hover{border-color:var(--fog);transform:translateY(-2px)}
  /* The hero pair speaks the same glossy-chip language as See Reviews and The
     Operator: deep-sea lacquer with a passing sheen for the primary, smoked
     glass for the secondary. Scoped to .cta-row -- .btn elsewhere stays flat. */
  .cta-row .btn{border-radius:6px}
  .cta-row .btn.primary{position:relative;overflow:hidden;font-weight:700;color:#EAF4FF;
    border:1px solid rgba(130,195,248,.45);
    background:linear-gradient(168deg,#2f5f88 0%,#1c3c5c 32%,#0e2338 62%,#234a6d 100%);
    box-shadow:0 8px 22px rgba(0,0,0,.55),inset 0 1px 0 rgba(165,218,255,.4),inset 0 -6px 12px rgba(0,0,0,.45)}
  .cta-row .btn.primary::after{content:"";position:absolute;top:0;bottom:0;width:38%;left:-60%;
    transform:skewX(-20deg);pointer-events:none;
    background:linear-gradient(90deg,transparent,rgba(255,255,255,.45),transparent);
    animation:goldSheen 4.5s ease-in-out infinite}
  .cta-row .btn:not(.primary){color:#E7E4DA;border:1px solid rgba(231,228,218,.4);
    background:rgba(10,16,24,.38);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px)}
  .cta-row .btn:not(.primary):hover{border-color:#fff;background:rgba(10,16,24,.55)}
  .cta-row .btn.primary:hover{filter:brightness(1.18);border-color:#7fc4ff;
    box-shadow:0 14px 30px rgba(0,0,0,.65),inset 0 1px 0 rgba(165,218,255,.5),inset 0 -6px 12px rgba(0,0,0,.45)}
  .btn .play{width:0;height:0;border-left:9px solid currentColor;border-top:6px solid transparent;border-bottom:6px solid transparent}


  /* ---------- shared section ---------- */
  .section{padding:clamp(72px,11svh,140px) clamp(24px,4vw,54px);max-width:1360px;margin:0 auto}
  .sec-head{display:flex;align-items:baseline;gap:18px;margin-bottom:52px;border-bottom:1px solid var(--line);padding-bottom:22px;flex-wrap:wrap}
  .sec-idx{font-family:var(--mono);font-size:0.75rem;letter-spacing:.16em;color:var(--signal)}
  .sec-title{font-family:var(--disp);font-weight:700;font-size:clamp(1.8rem,4vw,3rem);text-transform:uppercase;letter-spacing:-.01em;line-height:1}
  /* section notes always sit on ONE line — size shrinks before it ever wraps */
  .sec-note{margin-left:auto;font-family:var(--mono);font-size:clamp(.5rem,1.1vw,.6875rem);letter-spacing:.1em;text-transform:uppercase;color:var(--fog-dim);
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%;text-align:right}

  /* ---------- work grid ---------- */
  /* Recent work is a hands-on gallery: swipe or drag the rail directly, or
     use the two controls. The duplicate card set keeps exploration flowing
     without an abrupt dead end. */
  .work-rail{overflow-x:auto;overflow-y:hidden;scroll-behavior:smooth;scroll-snap-type:x proximity;
    scrollbar-width:none;cursor:grab;touch-action:pan-x pan-y;
    -webkit-mask-image:linear-gradient(90deg,transparent,#000 5%,#000 95%,transparent);
    mask-image:linear-gradient(90deg,transparent,#000 5%,#000 95%,transparent)}
  .work-rail::-webkit-scrollbar{display:none}
  .work-rail.is-dragging{cursor:grabbing;scroll-behavior:auto;user-select:none}
  .work-track{display:flex;gap:18px;width:max-content}
  .work-controls{display:flex;justify-content:flex-end;gap:8px;margin:0 0 14px}
  .work-nav{width:42px;height:38px;border:1px solid var(--line);border-radius:2px;background:var(--panel);
    color:var(--fog);font-size:1.25rem;line-height:1;cursor:pointer;transition:transform .2s ease,border-color .2s ease,color .2s ease,background .2s ease}
  .work-nav:hover{transform:translateY(-2px);border-color:var(--signal);background:rgba(69,160,232,.12);color:var(--signal)}
  .card{position:relative;overflow:hidden;background:var(--panel);border:1px solid var(--line-2);border-radius:5px;cursor:pointer;min-height:260px;display:flex;flex-direction:column;justify-content:flex-end;transition:transform .5s cubic-bezier(.2,.7,.2,1),border-color .35s ease,box-shadow .45s ease}
  .card:hover{transform:translateY(-6px);border-color:rgba(69,160,232,.5);box-shadow:0 20px 44px rgba(0,0,0,.52),0 0 0 1px rgba(69,160,232,.14)}
  .card::before{content:"";position:absolute;left:0;right:0;top:0;height:80px;z-index:1;pointer-events:none;
    background:linear-gradient(180deg,rgba(8,10,8,.45),transparent)}
  .work-track .card{flex:0 0 auto;width:clamp(280px,34vw,460px);height:clamp(300px,30vw,400px);min-height:0;scroll-snap-align:start}
  /* The work is the point: nothing sits over the photo. It carried
     brightness(.9), a card-wide scrim, a wash baked into each thumb's own
     background, AND a line-pattern overlay -- four layers of grey. Only the
     meta block keeps a scrim, because type needs one. */
  .card .thumb{position:absolute;inset:0;z-index:0;transition:transform .7s cubic-bezier(.2,.7,.2,1),filter .5s ease}
  .card:hover .thumb{transform:scale(1.07);filter:saturate(1.05)}
  .thumb.t1{background:linear-gradient(150deg,#213028,#0e1712 60%),radial-gradient(80% 60% at 70% 20%, rgba(255,120,60,.22),transparent)}
  .thumb.t2{background:linear-gradient(160deg,#1a2833,#0c1418 60%),radial-gradient(70% 60% at 30% 30%, rgba(120,170,190,.22),transparent)}
  .thumb.t3{background:linear-gradient(150deg,#2a2419,#12100b 60%),radial-gradient(70% 60% at 60% 25%, rgba(255,150,70,.2),transparent)}
  .thumb.t4{background:linear-gradient(160deg,#182420,#0d1310 60%),radial-gradient(70% 60% at 40% 20%, rgba(110,150,120,.22),transparent)}
  .thumb.t5{background:linear-gradient(150deg,#231d26,#100d12 60%),radial-gradient(70% 60% at 55% 25%, rgba(150,130,200,.16),transparent)}
  .thumb::after{content:"";position:absolute;inset:0;opacity:0;
    background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='400' height='300'%3E%3Cg fill='none' stroke='%23E7E4DA' stroke-opacity='0.08' stroke-width='1'%3E%3Cpath d='M0 80 C100 40 200 120 300 80 S 500 40 600 90'/%3E%3Cpath d='M0 140 C100 100 200 180 300 140 S 500 100 600 150'/%3E%3Cpath d='M0 200 C100 160 200 240 300 200 S 500 160 600 210'/%3E%3C/g%3E%3C/svg%3E")}
  .card .meta{position:relative;z-index:2;padding:22px;background:linear-gradient(transparent,rgba(9,11,9,.55) 32%,rgba(9,11,9,.92))}
  .card .role{font-family:var(--mono);font-size:0.6875rem;letter-spacing:.14em;text-transform:uppercase;color:var(--signal);margin-bottom:8px}
  .card .cname{font-family:var(--disp);font-weight:700;font-size:1.5rem;text-transform:uppercase;line-height:1}
  .card .cdesc{font-family:var(--mono);font-size:0.6875rem;letter-spacing:.08em;text-transform:uppercase;color:var(--fog-dim);margin-top:10px;
    max-height:0;opacity:0;overflow:hidden;transition:.4s ease}
  .card:hover .cdesc{max-height:40px;opacity:1}
  .card .frameno{position:absolute;top:14px;right:16px;z-index:2;font-family:var(--mono);font-size:0.625rem;
    letter-spacing:.1em;color:#E7E4DA;opacity:.72;text-shadow:0 1px 4px rgba(0,0,0,.85)}
  .card .pkg-badge{position:absolute;top:12px;left:14px;z-index:2;font-family:var(--mono);font-size:0.625rem;letter-spacing:.14em;text-transform:uppercase;color:var(--signal);background:rgba(10,12,10,.55);border:1px solid var(--line);border-radius:5px;padding:5px 9px;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}
  .card .pkg-badge[data-rate-link]{cursor:pointer;transition:color .2s ease,border-color .2s ease,background .2s ease}
  .card .pkg-badge[data-rate-link]:hover,.card .pkg-badge[data-rate-link]:focus-visible{color:var(--fog);border-color:var(--signal);background:rgba(12,29,39,.82);outline:none}
  .tier.rate-target{border-color:var(--signal)!important;box-shadow:0 0 0 2px rgba(69,160,232,.3),0 16px 36px rgba(0,0,0,.34)}


  /* ---------- archive strip ---------- */
  .arch{margin-top:26px;display:flex;align-items:center;gap:14px;flex-wrap:wrap;
    border-top:1px solid var(--line);padding-top:26px}
  .arch .al{font-family:var(--mono);font-size:0.625rem;letter-spacing:.18em;text-transform:uppercase;color:var(--fog-dim);margin-right:8px}
  .arch a{font-family:var(--mono);font-size:0.6875rem;letter-spacing:.14em;text-transform:uppercase;
    padding:12px 18px;border:1px solid var(--line);color:var(--fog);transition:.2s}
  .arch a:hover{border-color:var(--signal);color:var(--signal)}
  .arch a span{color:var(--fog-dim);margin-left:8px}




  /* Reviews CTA under the work rail — a struck-gold button, deliberately the
     only gold on the page so it reads as the one "proof" action. */
  /* the reviews CTA rides inside the section header, beside the title */
  .sec-head .btn-gold{align-self:center;padding:9px 15px;font-size:0.5938rem;letter-spacing:.14em;gap:7px}
  .sec-head .btn-gold svg{width:12px;height:12px}
  @media(max-width:700px){.sec-head .btn-gold{order:3}.sec-head .sec-note{order:4}}
  /* Client-words overlay: centred card that fades in rising from below and
     fades out sinking back down. */
  .rev-modal{position:fixed;inset:0;z-index:130;display:flex;align-items:center;justify-content:center;
    padding:clamp(16px,4vh,40px) clamp(14px,4vw,32px);opacity:0;pointer-events:none;
    transition:opacity .34s ease}
  .rev-modal.on{opacity:1;pointer-events:auto}
  .rev-veil{position:absolute;inset:0;background:rgba(8,10,8,.76);-webkit-backdrop-filter:blur(5px);backdrop-filter:blur(5px)}
  .rev-card{position:relative;width:min(620px,100%);max-height:86svh;overflow:auto;-webkit-overflow-scrolling:touch;
    background:linear-gradient(168deg,var(--panel-2),var(--basalt-2) 72%);
    border:1px solid var(--line);border-radius:14px;padding:26px clamp(18px,3vw,30px) 22px;
    box-shadow:0 30px 80px rgba(0,0,0,.66);
    transform:translateY(46px);opacity:0;
    transition:transform .42s cubic-bezier(.16,.84,.3,1),opacity .34s ease}
  .rev-modal.on .rev-card{transform:none;opacity:1}
  .rev-x{position:absolute;top:12px;right:12px;width:34px;height:34px;border:1px solid var(--line);border-radius:50%;
    background:transparent;color:var(--fog);font-size:1.1rem;line-height:1;cursor:pointer;transition:border-color .2s,color .2s}
  .rev-x:hover{border-color:var(--signal);color:var(--signal)}
  .rev-head{margin-bottom:18px;padding-right:40px}
  /* A spotlit dark room: one pool of light from above, the portrait standing
     in it, everything else falling away to black. The card re-declares the
     dark tokens, so the shared close button and rules read correctly. */
  .op-modal .rev-card{width:min(540px,100%);text-align:center;
    --fog:#E9F1F7;--fog-dim:#8CA3B8;--line:rgba(140,185,225,.16);--line-2:rgba(140,185,225,.09);
    color:var(--fog);
    background:
      radial-gradient(62% 44% at 50% 24%,rgba(105,140,175,.30),transparent 68%),
      radial-gradient(135% 115% at 50% 0%,#11161c 0%,#080b0f 52%,#04060a 100%);
    border:1px solid rgba(120,180,225,.15);
    box-shadow:0 40px 110px rgba(0,0,0,.85),inset 0 0 90px rgba(0,0,0,.55);
    padding:clamp(26px,4.5vw,36px) clamp(20px,4vw,34px) clamp(28px,4vw,36px)}
  /* the beam: a soft cone widening from the top edge down onto the portrait */
  .op-modal .rev-card::before{content:"";position:absolute;left:50%;top:0;width:78%;height:46%;
    transform:translateX(-50%);pointer-events:none;
    background:linear-gradient(180deg,rgba(170,205,240,.14),rgba(170,205,240,.05) 58%,transparent);
    clip-path:polygon(41% 0,59% 0,96% 100%,4% 100%);filter:blur(10px)}
  .rev-head h3{font-family:var(--disp);font-weight:800;font-size:1.35rem;text-transform:uppercase;letter-spacing:-.01em}
  .rev-note{display:block;margin-top:5px;font-family:var(--mono);font-size:.625rem;letter-spacing:.14em;text-transform:uppercase;color:var(--fog-dim)}
  .rev-list{display:flex;flex-direction:column;gap:16px}
  .rev-thread{border:1px solid var(--line-2);border-radius:11px;background:rgba(10,32,56,.045);padding:14px 15px}
  .rev-top{display:flex;align-items:center;gap:11px;margin-bottom:10px}
  .rev-logo{height:22px;width:auto;max-width:88px;object-fit:contain;flex:none}
  /* .inv = this mark was authored for the opposite ground. The card is light
     now, so it flags the near-white logos, not the dark ones. */
  .rev-logo.inv{filter:invert(1) grayscale(1) contrast(1.15)}
  .rev-brand{font-family:var(--disp);font-weight:700;font-size:.95rem;text-transform:uppercase;letter-spacing:.03em;flex:1;min-width:0}
  .rev-shot{width:46px;height:46px;border-radius:8px;object-fit:cover;flex:none;border:1px solid var(--line-2)}
  /* the quote as an incoming message bubble, tail on the left */
  .rev-bubble{position:relative;margin:0;border:0;padding:12px 14px;border-radius:12px 12px 12px 3px;
    background:linear-gradient(160deg,rgba(69,160,232,.16),rgba(69,160,232,.06));
    border-left:2px solid var(--signal);color:var(--fog);font-size:.95rem;line-height:1.55}
  .rev-who{margin-top:8px;font-family:var(--mono);font-size:.5625rem;letter-spacing:.14em;text-transform:uppercase;color:var(--fog-dim)}
  .rev-gbp{display:inline-block;margin-top:18px;font-family:var(--mono);font-size:.625rem;letter-spacing:.14em;
    text-transform:uppercase;color:var(--signal-ink)}
  .rev-gbp:hover{text-decoration:underline}
  @media (prefers-reduced-motion:reduce){.rev-modal,.rev-card{transition:none}}
  .btn-gold{position:relative;overflow:hidden;display:inline-flex;align-items:center;gap:9px;
    font-family:var(--mono);font-size:0.6875rem;letter-spacing:.16em;text-transform:uppercase;font-weight:700;
    color:#F2F0EA;padding:13px 22px;border-radius:4px;border:1px solid rgba(255,255,255,.18);text-decoration:none;
    background:linear-gradient(168deg,#3a3f39 0%,#1b1f1a 32%,#0b0d0a 62%,#20241e 100%);
    box-shadow:0 8px 22px rgba(0,0,0,.62),inset 0 1px 0 rgba(255,255,255,.34),inset 0 -6px 12px rgba(0,0,0,.5);
    transition:transform .2s ease,box-shadow .2s ease,filter .2s ease}
  .btn-gold svg{width:15px;height:15px;fill:#F2F0EA;flex:none;filter:drop-shadow(0 1px 2px rgba(0,0,0,.6))}
  /* glossy top-half highlight, like light sitting on lacquer */
  .btn-gold::before{content:"";position:absolute;left:0;right:0;top:0;height:48%;pointer-events:none;
    background:linear-gradient(180deg,rgba(255,255,255,.16),rgba(255,255,255,0));border-radius:4px 4px 0 0}
  .btn-gold::after{content:"";position:absolute;top:0;bottom:0;width:38%;left:-60%;transform:skewX(-20deg);
    background:linear-gradient(90deg,transparent,rgba(255,255,255,.5),transparent);
    animation:goldSheen 4.5s ease-in-out infinite}
  @keyframes goldSheen{0%,62%{left:-60%}88%,100%{left:130%}}
  .btn-gold:hover{transform:translateY(-2px);filter:brightness(1.18);
    box-shadow:0 14px 30px rgba(0,0,0,.7),inset 0 1px 0 rgba(255,255,255,.42),inset 0 -6px 12px rgba(0,0,0,.5)}
  .btn-gold:active{transform:translateY(0)}
  @media (prefers-reduced-motion:reduce){.btn-gold::after{animation:none}}
  /* Tinted variants of the glossy shell. They must sit AFTER .btn-gold and use
     the compound selector: earlier in the sheet, gold's later color/background
     declarations silently won and both chips rendered identical. */
  .btn-gold.btn-amber{color:#FFE9C4;border-color:rgba(224,165,82,.38);
    background:linear-gradient(168deg,#584327 0%,#2f2415 32%,#1a1106 62%,#3d2d18 100%);
    box-shadow:0 8px 22px rgba(0,0,0,.6),inset 0 1px 0 rgba(255,214,150,.38),inset 0 -6px 12px rgba(0,0,0,.5)}
  .btn-gold.btn-amber svg{fill:#FFD98F}
  .btn-gold.btn-amber:hover{box-shadow:0 14px 30px rgba(0,0,0,.68),inset 0 1px 0 rgba(255,214,150,.5),inset 0 -6px 12px rgba(0,0,0,.5)}
  .btn-gold.btn-blue{color:#DCEFFF;border-color:rgba(130,195,248,.32);
    background:linear-gradient(168deg,#2f4354 0%,#16242f 32%,#0a1420 62%,#1c2f3f 100%);
    box-shadow:0 8px 22px rgba(0,0,0,.6),inset 0 1px 0 rgba(165,218,255,.34),inset 0 -6px 12px rgba(0,0,0,.5)}
  .btn-gold.btn-blue svg{fill:#DCEFFF}
  .btn-gold.btn-blue:hover{box-shadow:0 14px 30px rgba(0,0,0,.68),inset 0 1px 0 rgba(165,218,255,.44),inset 0 -6px 12px rgba(0,0,0,.5)}

  /* Icon-only actions: the glyph alone, no shell. Everything the lacquer shell
     adds has to be undone explicitly, and this block must stay after
     .btn-amber/.btn-blue above. Not scoped to .sec-head -- JS moves these two
     buttons under the work rail on phones, and they must stay bare there. */
  .btn-gold.sec-ico{padding:7px;gap:0;border:0;border-radius:999px;
    background:none;box-shadow:none;overflow:visible;
    transition:transform .2s ease,background-color .2s ease}
  .btn-gold.sec-ico::before,
  .btn-gold.sec-ico::after{content:none}   /* gloss + sheen sweep */
  .btn-gold.sec-ico svg{width:24px;height:24px;filter:none;
    transition:transform .2s ease}
  .btn-gold.sec-ico:hover{transform:none;filter:none;box-shadow:none;
    background:rgba(10,32,56,.07)}
  .btn-gold.sec-ico:hover svg{transform:scale(1.12)}
  .btn-gold.sec-ico:active svg{transform:scale(1)}
  /* paper-ground accents; the shell's own fills were built for dark chips */
  .btn-gold.btn-amber.sec-ico svg{fill:#C08A22}
  .btn-gold.btn-blue.sec-ico svg{fill:#2E7BB5}
  .sec-ico .ico-t{position:absolute;width:1px;height:1px;margin:-1px;padding:0;
    overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}

  /* ---------- the operator ---------- */
  /* A light card against the dark veil: portrait, signature, one bold line.
     What stood here -- four animated capability tiles, a stats bar and three
     columns of bio -- took ~200 words to say what the photo and two sentences
     say faster. */
  .op-photo{position:relative;display:block;width:min(290px,68%);height:auto;margin:6px auto 0;border-radius:9px;
    border:1px solid rgba(230,240,255,.22);
    box-shadow:0 26px 60px rgba(0,0,0,.75),0 0 70px rgba(140,190,240,.16),inset 0 0 0 1px rgba(0,0,0,.4)}
  /* the name in the headline's own voice, lit by the pool above it */
  .op-sig{margin-top:24px;font-family:var(--disp);font-weight:800;
    font-size:clamp(1.7rem,5.6vw,2.35rem);line-height:1;letter-spacing:-.015em;
    text-transform:uppercase;color:#F4F9FD;
    text-shadow:0 0 26px rgba(150,195,240,.35),0 2px 14px rgba(0,0,0,.7)}
  .op-rule{width:52px;height:1px;margin:16px auto 0;background:var(--line);opacity:.85}
  .op-lead{margin:16px auto 0;max-width:44ch;text-wrap:balance;font-family:var(--mono);font-weight:700;
    font-size:.72rem;line-height:1.6;text-transform:uppercase;
    letter-spacing:.18em;color:#A9C2D8}
  .op-sub{margin:13px auto 2px;max-width:44ch;font-size:.82rem;line-height:1.75;
    letter-spacing:.02em;color:var(--fog-dim)}


  /* condensed pricing: the section runs tighter than the default, and the
     type tabs stay on ONE line — scrolling sideways on narrow screens rather
     than ever wrapping */
  #pricing{padding-top:clamp(44px,6.5svh,80px);padding-bottom:clamp(44px,6.5svh,80px)}
  #pricing .sec-head{margin-bottom:30px;padding-bottom:16px}
  .tt.active{color:var(--basalt);background:var(--signal);border-color:var(--signal);
    box-shadow:0 4px 16px rgba(69,160,232,.35)}
  .tier-set{display:block}
  .tier-set + .tier-set{margin-top:44px}
  .tier-set.rt-hidden{display:none}
  .tier-set.rt-hidden + .tier-set{margin-top:0}
  /* category tabs: one set on screen at a time, switched up top */
  /* Rates dropdown: the whole rates body (trust strip, tabs, tiers, add-ons,
     custom, usage rights) collapses behind one toggle. */
  .rates-drop{margin-top:28px;border:1px solid var(--line);border-radius:8px;background:linear-gradient(110deg,rgba(69,160,232,.08),transparent 42%),var(--panel);box-shadow:0 18px 38px rgba(0,0,0,.16);overflow:hidden}
  .rates-toggle{position:relative;isolation:isolate;list-style:none;cursor:pointer;display:flex;align-items:center;gap:16px;flex-wrap:wrap;
    min-height:82px;padding:20px clamp(20px,3vw,30px);border:0;border-left:3px solid var(--signal);background:transparent;
    font-family:var(--mono);font-size:.8125rem;letter-spacing:.14em;text-transform:uppercase;color:var(--fog);
    transition:background .2s ease,color .2s ease}
  .rates-toggle::before{content:"";position:absolute;z-index:-1;inset:0;background:linear-gradient(90deg,rgba(69,160,232,.1),transparent 50%);opacity:.7;transition:opacity .2s ease}
  .rates-toggle::-webkit-details-marker{display:none}
  .rates-toggle:hover{color:var(--signal)}.rates-toggle:hover::before{opacity:1}
  .rates-toggle .rt-hint{font-family:var(--mono);font-size:0.625rem;letter-spacing:.1em;color:var(--fog-dim);
    text-transform:uppercase;margin-left:auto;padding:8px 10px;border:1px solid var(--line-2);border-radius:999px;background:rgba(8,12,10,.2)}
  .rates-toggle .rt-chev{display:grid;place-items:center;margin-left:2px;width:30px;height:30px;border:1px solid currentColor;border-radius:50%;transform:rotate(45deg);transition:transform .25s ease,background .2s ease;flex:none}
  .rates-toggle .rt-chev::after{content:"";width:8px;height:8px;border-right:2px solid currentColor;border-bottom:2px solid currentColor}
  .rates-drop[open] .rates-toggle{color:var(--signal);background:rgba(69,160,232,.08)}
  .rates-drop[open] .rates-toggle .rt-chev{transform:rotate(-135deg);background:rgba(69,160,232,.16)}
  /* Control collapse explicitly (a global rule keeps native <details> content
     rendered) and force the scroll-reveal children visible once opened. */
  .rates-body{display:none;margin-top:30px}
  .rates-drop[open] .rates-body{display:block}
  .rates-drop[open] .rates-body .reveal{opacity:1!important;transform:none!important}
  @media(max-width:560px){.rates-toggle{min-height:0;gap:12px;padding:18px 18px 18px 20px}.rates-toggle .rt-hint{width:100%;order:3;margin-left:0;padding:0;border:0;background:none;line-height:1.5}.rates-toggle .rt-chev{margin-left:auto}}

  /* Real words, real marks: one client quote and the three client logos,
     monochrome, between the Rates head and the tabs. */
  .trust-strip{display:flex;align-items:center;justify-content:space-between;gap:26px;
    flex-wrap:wrap;margin:0 0 26px;padding:14px 18px;
    border:1px solid var(--line-2);border-radius:6px;background:var(--panel)}
  .tq{margin:0;font-size:.92rem;line-height:1.5;color:var(--fog);max-width:52ch}
  .tq cite{display:block;margin-top:4px;font-style:normal;font-family:var(--mono);
    font-size:.5625rem;letter-spacing:.14em;text-transform:uppercase;color:var(--fog-dim)}
  .rc-btn{display:inline-flex;align-items:center;gap:8px;flex:none;
    font-family:var(--mono);font-size:.625rem;font-weight:700;letter-spacing:.12em;
    text-transform:uppercase;color:var(--signal-ink);
    border:1px solid rgba(69,160,232,.45);border-radius:999px;padding:10px 15px;
    background:rgba(69,160,232,.08);transition:background .18s,border-color .18s,transform .18s}
  .rc-btn:hover{background:rgba(69,160,232,.16);border-color:var(--signal-ink);transform:translateY(-1px)}
  .rc-btn svg{width:14px;height:14px}
  .tmarks{display:flex;align-items:center;gap:26px;flex:none}
  .tmarks img{height:22px;width:auto;max-width:92px;object-fit:contain;
    filter:grayscale(1) contrast(1.05);opacity:.72}
  @media(max-width:700px){.trust-strip{justify-content:center;text-align:center}.tq{max-width:none}}
  .rate-tabs{display:flex;gap:10px;flex-wrap:wrap;justify-content:center;margin:0 auto 30px;padding:7px;width:fit-content;
    border:1px solid var(--line-2);border-radius:14px;
    background:linear-gradient(165deg,var(--panel-2),var(--basalt) 80%);
    box-shadow:inset 0 1px 0 rgba(255,255,255,.05),0 10px 26px rgba(0,0,0,.3)}
  .rt-tab{font-family:var(--mono);font-size:0.875rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
    padding:14px 26px;border:1px solid transparent;border-radius:10px;background:transparent;
    color:var(--fog-dim);cursor:pointer;transition:color .2s ease,background .2s ease,border-color .2s ease}
  /* phones: the three tabs split the full width as equal thirds on ONE row */
  @media(max-width:620px){
    .rate-tabs{width:100%;gap:6px;padding:5px}
    .rt-tab{flex:1;padding:12px 4px;font-size:0.625rem;letter-spacing:.04em;
      white-space:nowrap;text-align:center}
  }
  .rt-tab:hover{color:var(--fog)}
  .rt-tab.active{color:var(--basalt);background:linear-gradient(120deg,var(--signal),#7fc4ff);
    border-color:var(--signal);font-weight:700;box-shadow:0 6px 18px rgba(69,160,232,.35)}
  .tiers.tiers-2{grid-template-columns:repeat(2,1fr)}
  @media(max-width:620px){.tiers.tiers-2{grid-template-columns:1fr}}
  /* roster-size price brackets inside the merged Team Day card */
  /* roster brackets are the card's real price list, so they are pickable:
     the chosen row drives the price line and what the CTA sends to booking */
  .t-brackets{display:flex;flex-direction:column;border:1px solid var(--line-2);border-radius:5px;overflow:hidden}
  .tb-row{display:flex;align-items:baseline;gap:10px;width:100%;text-align:left;
    padding:9px 12px;font-size:.86rem;color:var(--fog);border:0;border-top:1px solid var(--line-2);
    background:transparent;cursor:pointer;transition:background .18s ease}
  .tb-row::before{content:"";flex:none;width:9px;height:9px;border-radius:50%;
    border:1.5px solid var(--fog-dim);align-self:center;transition:all .18s ease}
  .tb-row:first-child{border-top:0}
  .tb-row b{font-family:var(--disp);font-weight:800;color:#111;margin-left:auto}
  .tb-row:hover{background:rgba(231,228,218,.05)}
  .tb-row.sel{background:rgba(69,160,232,.12)}
  .tb-row.sel::before{background:var(--signal);border-color:var(--signal);box-shadow:0 0 9px rgba(69,160,232,.65)}
  .tb-row.sel b{color:var(--signal)}
  .tb-row.dim{color:var(--fog-dim);font-size:.78rem}
  .tb-row:focus-visible{outline:2px solid var(--signal);outline-offset:-2px}
  /* the licence, spelled out once for every package */
  .rights{margin-top:14px;border:1px solid var(--line-2);border-radius:5px;
    background:linear-gradient(165deg,var(--panel-2),var(--basalt) 75%);padding:20px 22px;
    box-shadow:inset 0 1px 0 rgba(255,255,255,.04),0 12px 28px rgba(0,0,0,.2)}
  /* A <details> disclosure. The summary keeps the headline and the one-line
     promise visible when collapsed, so the value still reads without opening. */
  .rights-head{display:flex;align-items:center;gap:11px;flex-wrap:wrap;cursor:pointer;
    list-style:none;padding-right:30px;position:relative;
    -webkit-tap-highlight-color:transparent}
  .rights-head::-webkit-details-marker{display:none}
  .rights-head::marker{content:""}
  .rights[open] .rights-head{margin-bottom:14px}
  .rights-chev{position:absolute;right:2px;top:50%;width:9px;height:9px;margin-top:-6px;
    border-right:2px solid var(--fog-dim);border-bottom:2px solid var(--fog-dim);
    transform:rotate(45deg);transition:transform .22s ease,border-color .2s ease}
  .rights[open] .rights-chev{transform:rotate(-135deg);margin-top:-2px}
  .rights-head:hover .rights-chev,.rights-head:focus-visible .rights-chev{border-color:var(--signal)}
  .rights-head:focus-visible{outline:2px solid var(--signal);outline-offset:4px;border-radius:3px}
  @media (prefers-reduced-motion:reduce){.rights-chev{transition:none}}
  .rights-head h3{font-family:var(--disp);font-weight:800;font-size:1.15rem;text-transform:uppercase;letter-spacing:-.01em}
  .rights-note{margin-left:auto;font-family:var(--mono);font-size:0.5938rem;letter-spacing:.14em;text-transform:uppercase;color:var(--fog-dim)}
  .rights-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px 22px}
  @media(max-width:860px){.rights-grid{grid-template-columns:1fr}}
  .rights-cell{font-size:.9rem;line-height:1.6;color:var(--fog-dim);padding:8px 0;border-top:1px solid var(--line-2)}
  .rights-cell b{color:var(--fog)}
  .rights-actions{display:flex;gap:10px;flex-wrap:wrap;margin-top:16px}
  .rights-btn{font-size:0.625rem;padding:12px 18px;border-color:rgba(31,111,180,.5);color:#155286;
    background:linear-gradient(120deg,rgba(69,160,232,.14),rgba(69,160,232,.04))}
  .rights-btn:hover{border-color:#1f6fb4;color:#0b3a63}
  .rights-btn.ghost{background:transparent;border-color:var(--line);color:var(--fog-dim)}
  .rights-btn.ghost:hover{border-color:var(--fog-dim);color:var(--fog)}
  /* licensing overlay: iconed schedule rows with the price in its own slab */
  .ur-modal .rev-card{width:min(680px,100%)}
  .url-list{display:flex;flex-direction:column}
  .url-row{display:flex;gap:13px;align-items:flex-start;padding:13px 0;border-top:1px solid var(--line-2)}
  .url-row:first-child{border-top:0}
  .url-txt{flex:1;min-width:0}
  .url-txt strong{display:block;font-family:var(--body);font-size:1rem;font-weight:600;color:var(--fog);line-height:1.3;margin-bottom:3px}
  .url-txt span{font-size:.86rem;color:var(--fog-dim);line-height:1.5}
  .url-price{flex:none;min-width:118px;text-align:center;padding:8px 10px;border-radius:7px;
    border:1px solid rgba(69,160,232,.3);background:linear-gradient(160deg,rgba(69,160,232,.14),rgba(69,160,232,.04))}
  .url-price b{display:block;font-family:var(--disp);font-weight:800;font-size:1.08rem;color:#1B5C97;white-space:nowrap}
  .url-price em{display:block;font-family:var(--mono);font-style:normal;font-size:0.5rem;letter-spacing:.1em;
    text-transform:uppercase;color:var(--fog-dim);margin-top:3px}
  .ur-foot{margin-top:14px;padding-top:14px;border-top:1px solid var(--line-2);
    display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;
    font-size:.88rem;color:var(--fog-dim)}
  @media(max-width:560px){
    .url-row{flex-wrap:wrap}
    .url-price{min-width:0;flex:1 1 100%;display:flex;align-items:baseline;justify-content:space-between;padding:7px 12px}
    .url-price em{margin-top:0}
  }
  .tier-group{font-family:var(--mono);font-size:0.6875rem;letter-spacing:.2em;text-transform:uppercase;
    color:var(--signal-ink);margin:0 0 16px;padding-bottom:10px;border-bottom:1px solid var(--line-2)}
  /* ---------- pricing cards: precision-gear treatment ----------
     Cards read as physical objects under a key light: layered material
     gradients, pointer-tracked 3D tilt with a cursor-following glare (JS feeds
     --gx/--gy), a dealt-in cascade every time a set becomes visible, and a
     revolving light ring around the featured card. */
  .tiers{display:grid;grid-template-columns:repeat(3,1fr);gap:18px;align-items:stretch;perspective:1400px}
  .tiers.tiers-4{grid-template-columns:repeat(4,1fr)}
  @media(max-width:1100px){.tiers.tiers-4{grid-template-columns:repeat(2,1fr)}}
  @media(max-width:620px){.tiers.tiers-4{grid-template-columns:1fr}}
  /* Five packages in a four-across grid left one card alone beside three empty
     columns. On a six-column track each card spans two, so the set reads 3 + 2
     with the short row centred rather than stranded at the left edge. */
  .tiers.tiers-5{grid-template-columns:repeat(6,1fr)}
  .tiers.tiers-5 > .tier{grid-column:span 2}
  .tiers.tiers-5 > .tier:nth-child(4){grid-column:2 / span 2}
  .tiers.tiers-5 > .tier:nth-child(5){grid-column:4 / span 2}
  @media(max-width:1100px){
    .tiers.tiers-5{grid-template-columns:repeat(4,1fr)}
    .tiers.tiers-5 > .tier:nth-child(4){grid-column:span 2}
    .tiers.tiers-5 > .tier:nth-child(5){grid-column:2 / span 2}}
  @media(max-width:620px){
    .tiers.tiers-5{grid-template-columns:1fr}
    .tiers.tiers-5 > .tier,
    .tiers.tiers-5 > .tier:nth-child(4),
    .tiers.tiers-5 > .tier:nth-child(5){grid-column:auto}}
  /* Deliverables at a glance: what you get, readable without reading. The
     rows below still carry the detail. */
  .t-glance{display:flex;gap:7px;margin:0;padding:0;list-style:none}
  .t-glance li{flex:1 1 0;min-width:0;display:flex;flex-direction:column;align-items:center;
    gap:4px;padding:9px 5px;border:1px solid var(--line-2);border-radius:6px;
    background:rgba(69,160,232,.06);text-align:center}
  .t-glance svg{width:16px;height:16px;fill:none;stroke:var(--signal-ink);
    stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
  .t-glance b{font-family:var(--disp);font-weight:800;font-size:.92rem;color:var(--fog);line-height:1.05}
  .t-glance i{font-style:normal;font-family:var(--mono);font-size:.5rem;letter-spacing:.1em;
    text-transform:uppercase;color:var(--fog-dim);line-height:1.2}
  @media(max-width:620px){.t-glance b{font-size:.86rem}.t-glance li{padding:8px 4px}}
  .tier{--lift:0px;--scale:1;--rx:0deg;--ry:0deg;position:relative;overflow:hidden;border:1px solid var(--line-2);border-radius:5px;
    background:linear-gradient(165deg,#FFFFFF,#F1F0E8 72%);
    padding:22px 20px;display:flex;flex-direction:column;gap:13px;
    box-shadow:inset 0 1px 0 #fff,0 12px 32px rgba(20,24,18,.12);
    transform:translateY(var(--lift)) rotateX(var(--rx)) rotateY(var(--ry)) scale(var(--scale));
    transform-style:preserve-3d;transition:transform .45s cubic-bezier(.2,.7,.2,1),box-shadow .45s ease,border-color .3s ease;
    will-change:transform}
  .tier:hover{border-color:rgba(69,160,232,.4);
    box-shadow:inset 0 1px 0 rgba(255,255,255,.07),0 30px 60px rgba(0,0,0,.55),0 0 34px rgba(69,160,232,.12)}
  .tier::after{content:"";position:absolute;inset:0;pointer-events:none;opacity:0;transition:opacity .35s ease;
    background:radial-gradient(340px circle at var(--gx,50%) var(--gy,40%),rgba(160,215,255,.13),transparent 62%)}
  .tier:hover::after{opacity:1}
  .tier-set .tier{animation:tierIn .6s cubic-bezier(.16,.8,.26,1) backwards}
  .tier-set .tier:nth-child(2){animation-delay:.07s}
  .tier-set .tier:nth-child(3){animation-delay:.14s}
  .tier-set .tier:nth-child(4){animation-delay:.21s}
  @keyframes tierIn{from{opacity:0;transform:translateY(26px) rotateX(-8deg) scale(.98)}}
  /* featured card: pedestal scale, ambient glow, revolving light ring
     (@property lets the conic angle animate; older engines get a static ring) */
  @property --ring{syntax:'<angle>';initial-value:0deg;inherits:false}
  .tier.hot{--scale:1.03;border-color:transparent;
    box-shadow:inset 0 1px 0 rgba(255,255,255,.07),0 18px 44px rgba(0,0,0,.5),0 0 44px rgba(69,160,232,.14)}
  .tier.hot::before{content:"";position:absolute;inset:0;border-radius:5px;padding:1.5px;pointer-events:none;z-index:1;
    background:conic-gradient(from var(--ring),rgba(69,160,232,.16),rgba(69,160,232,.85) 12%,rgba(200,235,255,.95) 16%,rgba(69,160,232,.85) 20%,rgba(69,160,232,.16) 42%,rgba(69,160,232,.16));
    -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
    -webkit-mask-composite:xor;
    mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
    mask-composite:exclude;
    animation:ringSpin 5s linear infinite}
  @keyframes ringSpin{to{--ring:360deg}}
  .tier.hot{padding-top:43px}
  .t-badge{position:absolute;top:14px;left:20px;overflow:hidden;border-radius:2px;z-index:2;
    background:linear-gradient(120deg,var(--signal),#7fc4ff);color:var(--basalt);
    font-family:var(--mono);font-size:0.625rem;font-weight:700;letter-spacing:.16em;text-transform:uppercase;
    padding:4px 10px;box-shadow:0 4px 14px rgba(69,160,232,.4)}
  .t-badge::after{content:"";position:absolute;top:0;bottom:0;width:40%;left:-60%;transform:skewX(-20deg);
    background:linear-gradient(90deg,transparent,rgba(255,255,255,.7),transparent);
    animation:badgeShine 3.4s ease-in-out infinite}
  @keyframes badgeShine{0%,55%{left:-60%}85%,100%{left:130%}}
  .t-badge.alt{background:linear-gradient(120deg,#b3d98f,#7fbf5a)}
  .tier.tagged{padding-top:43px}
  /* the single quick add-on that bridges The Menu -> The Seasonal */
  /* an offered extra, not a disabled input: accent tint, solid hairline, and
     a plus that marks it as additive */
  .t-addon{margin-top:-4px;display:flex;align-items:center;gap:8px;
    font-family:var(--mono);font-size:0.625rem;letter-spacing:.06em;text-transform:uppercase;
    color:var(--signal-ink);border:1px solid rgba(69,160,232,.4);border-radius:999px;
    background:rgba(69,160,232,.1);padding:7px 12px;line-height:1.5}
  .t-addon::before{content:"+";flex:none;width:16px;height:16px;border-radius:50%;
    display:flex;align-items:center;justify-content:center;
    background:var(--signal-ink);color:#fff;font-weight:700;font-size:.7rem}
  .t-addon b{color:var(--signal-ink);font-weight:700}
  /* hospitality add-on rail + production guarantee */
  .hosp-extras{margin-top:16px;display:grid;grid-template-columns:1.35fr 1fr;gap:14px}
  @media(max-width:860px){.hosp-extras{grid-template-columns:1fr}}
  .hx-addons,.hx-note{border:1px solid var(--line-2);border-radius:5px;background:var(--panel);padding:16px 18px}
  .hx-addons b{display:block;font-family:var(--mono);font-size:0.625rem;letter-spacing:.16em;text-transform:uppercase;
    color:var(--signal-ink);margin-bottom:9px}
  /* one add-on per row: name, plain-English description, price in its own column.
     The old single-line "name / dot / description / price" run-ons were hard to
     scan, and the price landed wherever the text happened to wrap. */
  .hx-row{display:flex;align-items:flex-start;gap:14px;padding:12px 0;border-top:1px solid var(--line)}
  .hx-row:first-of-type{border-top:0;padding-top:4px}
  .hx-txt{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}
  .hx-txt strong{font-family:var(--body);font-size:.98rem;font-weight:600;color:#141712;line-height:1.3}
  .hx-txt span{font-size:.88rem;color:var(--fog-dim);line-height:1.5}
  .hx-addons i{font-style:normal;flex:none;font-family:var(--disp);font-weight:800;font-size:1.06rem;
    color:var(--signal-ink);white-space:nowrap;padding-top:1px}
  /* One line answering the only question a restaurant actually has about the
     shoot: will it get in the way of service. The heading and the second
     sentence were saying it twice. */
  .hx-note{display:flex;align-items:center;padding:16px 18px;
    font-size:.95rem;color:var(--fog-dim);line-height:1.55}
  .t-name{font-family:var(--disp);font-weight:800;font-size:1.2rem;text-transform:uppercase;letter-spacing:-.01em}
  /* metallic numerals with a slow glint passing through, staggered per card */
  .t-price{font-family:var(--disp);font-weight:800;font-size:clamp(1.6rem,2.6vw,2.1rem);line-height:1;
    padding-bottom:12px;border-bottom:1px solid var(--line);
    background-image:linear-gradient(105deg,#20241F 0%,#20241F 38%,#2f6ea8 50%,#20241F 62%,#20241F 100%);
    background-size:240% 100%;-webkit-background-clip:text;background-clip:text;color:transparent;
    animation:priceGlint 7s ease-in-out infinite}
  .tier:nth-child(2) .t-price{animation-delay:1.4s}
  .tier:nth-child(3) .t-price{animation-delay:2.8s}
  .tier:nth-child(4) .t-price{animation-delay:4.2s}
  @keyframes priceGlint{0%,55%{background-position:120% 0}90%,100%{background-position:-40% 0}}
  .tier.hot .t-price{background-image:linear-gradient(105deg,#1f6fb4 0%,#1f6fb4 45%,#66a9e0 52%,#1f6fb4 60%,#1f6fb4 100%)}
  .t-price span{font-family:var(--mono);font-size:0.6875rem;font-weight:400;letter-spacing:.14em;text-transform:uppercase;color:var(--fog-dim)}
  /* Spec grid: every card in a set carries the same four labelled rows in the
     same order (shoot/photos/video/delivery, or people/session/looks/set), so
     reading across the row compares the packages instead of re-reading prose.
     Rows share a min-height on the 4-across layout so they line up card to card. */
  .t-spec{display:flex;flex-direction:column}
  .ts-row{display:flex;gap:11px;align-items:flex-start;padding:9px 0;border-top:1px solid var(--line-2)}
  .ts-row:first-child{border-top:0;padding-top:2px}
  .ts-i{flex:none;width:26px;height:26px;border-radius:7px;display:grid;place-items:center;margin-top:1px;
    border:1px solid rgba(69,160,232,.28);background:linear-gradient(160deg,rgba(69,160,232,.16),rgba(69,160,232,.04));
    box-shadow:inset 0 1px 0 rgba(255,255,255,.08)}
  .ts-i svg{width:14px;height:14px;fill:none;stroke:#9fd4ff;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
  .ts-c{min-width:0;display:flex;flex-direction:column;gap:2px}
  .ts-k{font-family:var(--mono);font-size:0.5625rem;letter-spacing:.16em;text-transform:uppercase;color:var(--fog-dim)}
  .ts-v{font-size:.86rem;color:var(--fog);line-height:1.4}
  .ts-v b{font-weight:700;color:#111}
  .ts-v .dim{color:var(--fog-dim)}
  /* On the 4-across layout the rows are a comparison table in disguise, so they
     have to sit at the same y in every card: every card gets the badge cards'
     top padding (uniform headers), and each row reserves two value lines. */
  @media(min-width:1101px){
    .tiers-4 .tier,.tiers-5 .tier{padding-top:43px}
    .ts-row{min-height:79px}   /* a two-line value row measures ~78px at the 17px base */
  }
  /* the long "growing brands" badge must hold one line, or it lands on the
     card name -- the header only reserves a single badge row */
  @media(min-width:1101px) and (max-width:1330px){
    .t-badge{letter-spacing:.07em;font-size:0.5625rem;white-space:nowrap}
  }
  /* Narrow columns (a three-across events row at tablet width) get a compact
     treatment instead of collapsing to a stack -- the row itself is the point. */
  @media(min-width:621px) and (max-width:1100px){
    .tiers{gap:10px}
    .tier{padding:16px 12px;gap:10px}
    .tier.hot,.tier.tagged{padding-top:38px}
    .t-badge{top:11px;left:12px;font-size:0.5rem;letter-spacing:.06em;white-space:nowrap;
      max-width:calc(100% - 24px);overflow:hidden;text-overflow:ellipsis}
    .t-name{font-size:1rem}
    .t-price{font-size:1.4rem;padding-bottom:9px}
    .t-price span{font-size:0.5625rem}
    .ts-i{width:22px;height:22px;border-radius:6px}
    .ts-i svg{width:12px;height:12px}
    .ts-row{gap:8px;padding:7px 0}
    .ts-k{font-size:0.5rem}
    .ts-v{font-size:.78rem}
    .t-incl{padding-top:8px;gap:5px}
    .ti-row{font-size:.72rem;padding-left:17px}
    .t-choose{padding:9px 8px;font-size:0.5938rem;letter-spacing:.08em}
    .tb-row{padding:7px 9px;font-size:.78rem;gap:8px}
    .t-addon{font-size:0.5rem;padding:6px 7px}
  }
  /* the shorter "also included" checks under the spec rows */
  .t-incl{display:flex;flex-direction:column;gap:6px;flex:1;padding-top:10px;border-top:1px solid var(--line-2)}
  .ti-row{position:relative;padding-left:20px;font-size:.8rem;color:var(--fog-dim);line-height:1.45}
  .ti-row b,.ti-row em{color:var(--fog)}
  .ti-row svg{position:absolute;left:0;top:.22em;width:12px;height:12px;fill:none;stroke:var(--field);
    stroke-width:2.6;stroke-linecap:round;stroke-linejoin:round}
  /* a card with no extra checks still pushes its button to the bottom */
  .t-spec:last-of-type{flex:1}
  .t-choose{margin-top:2px;font-family:var(--mono);font-size:0.6875rem;letter-spacing:.12em;text-transform:uppercase;
    padding:11px 14px;border:1px solid rgba(10,32,56,.3);border-radius:3px;background:transparent;color:var(--fog);
    cursor:pointer;text-align:center;position:relative;z-index:2;
    transition:border-color .2s ease,color .2s ease,background .2s ease,transform .2s ease,box-shadow .2s ease}
  .t-choose:hover{border-color:var(--signal);color:#0b3a63;transform:translateY(-2px);
    background:linear-gradient(120deg,rgba(69,160,232,.22),rgba(69,160,232,.05));
    box-shadow:0 8px 22px rgba(69,160,232,.25)}
  /* white on --signal is 2.56:1; this tone of the same hue is 4.5:1 */
  .tier.hot .t-choose{background:#357BB3;border-color:#357BB3;color:#fff;font-weight:700;
    box-shadow:0 6px 18px rgba(69,160,232,.35)}
  .tier.hot .t-choose:hover{background:#5fb0f0;color:#fff;transform:translateY(-2px);
    box-shadow:0 10px 26px rgba(69,160,232,.5)}
  #f-package.just-set{border-color:var(--signal);box-shadow:0 0 0 2px rgba(69,160,232,.28)}
  .f-field.is-disabled label{color:var(--field-dim)}
  .f-field select:disabled{opacity:.45;cursor:not-allowed;border-color:var(--line-2);color:var(--fog-dim)}
  /* One quiet line, not a second pitch: icon, what else gets shot, and the
     way in. Everything the paragraph used to say is in those five words. */
  .tier-custom{position:relative;margin-top:14px;border:1px solid var(--line-2);
    background:var(--panel);padding:14px 18px;border-radius:5px;
    display:flex;align-items:center;gap:14px;flex-wrap:wrap}
  .tc-icon{flex:none;display:grid;place-items:center;width:34px;height:34px;border-radius:50%;
    color:var(--signal-ink);background:rgba(69,160,232,.1)}
  .tc-icon svg{width:18px;height:18px}
  .tc-txt{flex:1 1 240px;min-width:0;color:var(--fog-dim);font-size:.95rem;margin:0}
  .tc-txt b{color:var(--fog);font-weight:600}
  .tier-custom .btn{flex:none;margin-left:auto}
  @media(max-width:620px){.tier-custom .btn{margin-left:0;width:100%;justify-content:center}}
  @media(max-width:620px){.tiers{grid-template-columns:1fr}}
  @media (prefers-reduced-motion:reduce){.tier,.tier.hot{transform:translateY(0) scale(var(--scale));transition:none}.tier-set .tier,.tier.hot::before,.t-badge::after,.t-price{animation:none}.tier::after{display:none}}
  /* ---------- booking ---------- */
  /* the whole booking card is contained rather than full-bleed, so the form
     reads as a compact panel instead of a page-wide block */
  .book{position:relative;border:1px solid var(--line);background:var(--panel);overflow:hidden}
  .book::before{content:"";position:absolute;inset:0;opacity:.28;
    background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='700' height='500'%3E%3Cg fill='none' stroke='%236C8060' stroke-opacity='0.14' stroke-width='1'%3E%3Cpath d='M0 120 C120 70 260 170 420 120 S 640 70 760 130'/%3E%3Cpath d='M0 220 C120 170 260 270 420 220 S 640 170 760 230'/%3E%3Cpath d='M0 320 C120 270 260 370 420 320 S 640 270 760 330'/%3E%3C/g%3E%3C/svg%3E")}
  /* compact booking: tighter section, smaller headline, denser form */
  #booking{padding-top:clamp(34px,5svh,60px);padding-bottom:clamp(34px,5svh,60px)}
  /* A band of deep water behind the booking card. Full-bleed via a pseudo
     element, because .section is a max-width:1360px centred column. */
  #booking{position:relative}
  #booking::before{content:"";position:absolute;left:50%;top:0;bottom:0;width:100vw;
    transform:translateX(-50%);z-index:0;pointer-events:none;
    background:linear-gradient(180deg,#0A1F36 0%,#071829 55%,#0B2138 100%)}
  #booking > *{position:relative;z-index:1}
  .book-in{position:relative;z-index:2;padding:clamp(22px,3vw,34px)}
  .status{display:inline-flex;align-items:center;gap:10px;font-family:var(--mono);font-size:0.6875rem;letter-spacing:.14em;text-transform:uppercase;color:var(--field);border:1px solid var(--fog-dim);padding:6px 11px;margin-bottom:14px}
  /* the status / title / email block is centred as a masthead over the form */
  .book-in > .status{display:flex;width:fit-content;margin-inline:auto}
  .status .lg{width:8px;height:8px;border-radius:50%;background:var(--field);box-shadow:0 0 0 3px rgba(108,128,96,.25);animation:blink 1.6s steps(1) infinite}
  .book h2{font-family:var(--disp);font-weight:800;font-size:clamp(1.7rem,3.4vw,2.6rem);text-transform:uppercase;line-height:1;letter-spacing:-.02em;text-align:center}
  /* plain sentence-case sans, so the address is easy to read and to copy */
  .book-cta .btn{white-space:nowrap;font-family:var(--body);font-size:1rem;font-weight:500;
    letter-spacing:.01em;text-transform:none;padding:13px 24px}
  .book-cta{margin-top:14px;display:flex;gap:12px;flex-wrap:wrap;justify-content:center}


  /* ---------- booking form ----------
     Deliberately plain and linear. One question per row, labels at reading size,
     help text under each one, and "required" spelled out instead of an asterisk.
     The old version put 9px uppercase labels on a two-column grid, which is hard
     going for anyone not already fluent in web forms. */
  /* Booking masthead. All three lines used to run at almost one size in one
     dim grey, so the block read as a single paragraph interrupted by a button.
     Now: the promise in ink, its caveat stepped back, and the aside demoted to
     a footnote under a short rule. */
  .book-lede{max-width:46ch;margin:12px auto 0;text-align:center;
    font-size:clamp(1.08rem,1.5vw,1.2rem);line-height:1.55;letter-spacing:-.006em;color:var(--fog);
    text-wrap:balance}
  .book-lede em{display:block;margin-top:7px;font-style:normal;
    font-size:.9em;line-height:1.5;color:var(--fog-dim);text-wrap:balance}
  .book-alt{position:relative;max-width:42ch;margin:16px auto 0;padding-top:14px;text-align:center;
    font-size:.86rem;line-height:1.6;color:var(--fog-dim);text-wrap:balance}
  .book-alt::before{content:"";position:absolute;top:0;left:50%;width:38px;height:1px;
    transform:translateX(-50%);background:var(--line)}
  /* The optional tail of the booking form -- reference links and add-ons --
     folded behind one disclosure so the visible form stays three short steps. */
  .f-more{grid-column:1/-1;border:1px solid var(--line);border-radius:8px;background:var(--panel)}
  .f-more > summary{list-style:none;cursor:pointer;display:flex;align-items:center;gap:10px;
    padding:14px 16px;font-family:var(--mono);font-size:.6875rem;font-weight:700;
    letter-spacing:.12em;text-transform:uppercase;color:var(--fog-dim);
    transition:color .18s}
  .f-more > summary::-webkit-details-marker{display:none}
  .f-more > summary::after{content:"";margin-left:auto;flex:none;width:8px;height:8px;
    border-right:1.6px solid currentColor;border-bottom:1.6px solid currentColor;
    transform:translateY(-2px) rotate(45deg);transition:transform .2s}
  .f-more[open] > summary::after{transform:translateY(1px) rotate(225deg)}
  .f-more > summary:hover,.f-more[open] > summary{color:var(--fog)}
  .f-more-body{display:flex;flex-direction:column;gap:16px;padding:2px 16px 18px}
  .bform{margin:20px auto 0;border-top:1px solid var(--line);padding-top:22px;
    display:flex;flex-direction:column;gap:22px;max-width:760px}
  /* numbered step groups: three small tasks instead of one wall of fields */
  /* min-inline-size:0 matters: a fieldset defaults to min-content, so one long
     unbreakable string (a pasted URL in a link card) would otherwise push the
     whole step wider than the card and get clipped on phones. */
  .fstep{border:0;padding:0;margin:0;min-inline-size:0;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px 16px}
  .fstep legend{grid-column:1/-1;float:left;width:100%}
  .fstep legend+*{clear:both}
  /* long-form rows keep the full width */
  .f-field.f-wide,.f-field:has(textarea),
  .f-field:has(.addon-row),.f-field:has(#f-refs),.f-field:has(#est-box),.f-field:has(.est-line){grid-column:1/-1}
  @media(max-width:640px){.fstep{grid-template-columns:1fr}}
  .fstep > legend{display:flex;align-items:center;gap:12px;padding:0;margin-bottom:2px;
    font-family:var(--disp);font-weight:700;font-size:1.2rem;line-height:1.3;color:var(--fog)}
  .fstep-n{flex:none;display:flex;align-items:center;justify-content:center;
    width:30px;height:30px;border-radius:50%;background:var(--signal);color:#08111A;
    font-family:var(--mono);font-size:.8rem;font-weight:700}
  /* Two fields sharing a row rarely carry the same amount of help text, so
     their inputs used to land at different heights and the whole form read as
     ragged. The field fills its grid row and the control is pushed to the
     bottom of it, which lines every input in the row up on one baseline. */
  .f-field{display:flex;flex-direction:column;gap:8px;align-self:stretch}
  .f-field > input,.f-field > select,.f-field > textarea,
  .f-field > .linkin,.f-field > .addon-row{margin-top:auto}
  /* .f-field's display would otherwise beat the browser's [hidden] rule, which is
     why the estimate box used to sit there reading $0 before anything was picked */
  .f-field[hidden]{display:none}
  .f-field label{font-family:var(--body);font-size:1.03rem;font-weight:600;color:var(--fog);
    letter-spacing:0;text-transform:none;display:flex;align-items:center;gap:10px;flex-wrap:wrap}
  .req,.opt{font-family:var(--mono);font-size:0.5625rem;font-weight:400;letter-spacing:.12em;
    text-transform:uppercase;padding:3px 8px;border-radius:3px}
  .req{color:#7A5410;background:rgba(216,162,74,.18);border:1px solid rgba(150,104,28,.45)}
  .opt{color:var(--fog-dim);background:rgba(231,228,218,.05);border:1px solid var(--line)}
  .f-help{font-family:var(--body);font-size:.92rem;line-height:1.55;color:var(--fog-dim);margin:-3px 0 1px;max-width:64ch}
  .f-help b{color:var(--fog);font-weight:600}
  .f-field input,.f-field select,.f-field textarea{
    background:#F7FAFC;border:1px solid rgba(10,32,56,.24);color:var(--fog);
    padding:11px 13px;min-height:46px;font-family:var(--body);font-size:1rem;
    border-radius:6px;appearance:none;-webkit-appearance:none;outline:none;
    transition:border-color .2s,box-shadow .2s}
  .f-field select{cursor:pointer;padding-right:44px;
    background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='9'%3E%3Cpath d='M0 0l7 9 7-9z' fill='%23E7E4DA'/%3E%3C/svg%3E");
    background-repeat:no-repeat;background-position:right 16px center}
  /* date field: keep the native picker but make its icon visible on dark */
  .f-field input[type=date]::-webkit-calendar-picker-indicator{filter:invert(.85);cursor:pointer;opacity:.8;width:22px;height:22px}
  .f-field input[type=date]::-webkit-calendar-picker-indicator:hover{opacity:1}
  .f-date input{max-width:320px}
  .f-field textarea{min-height:96px;resize:vertical;line-height:1.55}
  /* a focus ring you cannot miss, not a one-pixel colour shift */
  .f-field input:focus,.f-field select:focus,.f-field textarea:focus{
    border-color:var(--signal);box-shadow:0 0 0 3px rgba(69,160,232,.3)}
  .f-field input:user-invalid,.f-field select:user-invalid,.f-field textarea:user-invalid{
    border-color:#E5484D;box-shadow:0 0 0 3px rgba(229,72,77,.22)}
  .f-field ::placeholder{color:var(--fog-dim);opacity:.6}
  /* reference links: paste one, press Enter, and it becomes a card you can remove.
     Easier than asking someone to comma-separate URLs in a single box. */
  .linkin{display:flex;gap:10px;align-items:stretch}
  .linkin input{flex:1;min-width:0}
  .linkin-go{flex:none;width:56px;display:flex;align-items:center;justify-content:center;cursor:pointer;
    /* --signal on its own pale tint is 2.24:1; this darker tone is 4.5:1 */
    border-radius:6px;color:var(--signal-ink);background:rgba(69,160,232,.14);border:1px solid rgba(69,160,232,.45);
    transition:background .2s ease,border-color .2s ease}
  .linkin-go:hover{background:rgba(69,160,232,.26);border-color:var(--signal)}
  .linkin-go svg{width:22px;height:22px;fill:none;stroke:currentColor;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}
  .linkin-err{margin:0;font-family:var(--body);font-size:.9rem;line-height:1.5;color:#F0908F}
  .linkin-err[hidden]{display:none}
  .linklist{list-style:none;margin:2px 0 0;padding:0;display:flex;flex-direction:column;gap:8px}
  .linklist[hidden]{display:none}
  .linkcard{display:flex;align-items:center;gap:12px;padding:9px 11px;
    border:1px solid rgba(10,32,56,.22);border-radius:6px;background:#F7FAFC}
  .lc-thumb{flex:none;width:96px;height:54px;object-fit:cover;border-radius:4px;background:#000}
  .lc-icon{flex:none;width:46px;height:46px;border-radius:4px;display:flex;align-items:center;justify-content:center;
    background:rgba(69,160,232,.16);color:var(--signal-ink);font-family:var(--disp);font-weight:800;font-size:1.15rem}
  .lc-txt{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
  .lc-txt strong{font-family:var(--body);font-size:.98rem;font-weight:600;color:var(--fog)}
  .lc-txt span{font-family:var(--mono);font-size:.72rem;color:var(--fog-dim);
    overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .lc-x{flex:none;width:38px;height:38px;border-radius:50%;cursor:pointer;font-size:1.35rem;line-height:1;
    display:flex;align-items:center;justify-content:center;
    background:transparent;border:1px solid var(--line-2);color:var(--fog-dim);
    transition:border-color .2s ease,color .2s ease,background .2s ease}
  .lc-x:hover{border-color:#E5484D;color:#F0908F;background:rgba(229,72,77,.1)}
  /* add-ons: full rows with a real tick, priced in plain figures */
  .addon-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(272px,1fr));gap:10px}
  .addon{display:flex;align-items:center;gap:13px;cursor:pointer;
    border:1px solid var(--line-2);border-radius:6px;background:rgba(10,32,56,.07);padding:15px 16px;
    font-family:var(--body);font-size:1rem;letter-spacing:0;text-transform:none;color:var(--fog);
    transition:border-color .2s ease,background .2s ease}
  .addon:hover{border-color:var(--fog-dim)}
  .addon b{margin-left:auto;color:var(--signal-ink);font-weight:700;white-space:nowrap}
  /* the shared .f-field input rule sets min-height:54px, which would stretch
     these into tall slivers -- reset it so the box stays square */
  .addon input{appearance:none;-webkit-appearance:none;flex:none;width:24px;height:24px;
    min-height:24px;margin:0;padding:0;
    cursor:pointer;border:2px solid var(--fog-dim);border-radius:5px;background:rgba(10,32,56,.1);
    transition:background .15s ease,border-color .15s ease}
  .addon input:checked{border-color:var(--signal);
    background:var(--signal) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20 6L9 17l-5-5' fill='none' stroke='%2308111A' stroke-width='3.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/15px 15px no-repeat}
  .addon:has(input:checked){border-color:var(--signal);background:rgba(69,160,232,.1)}
  .est-line{display:flex;justify-content:space-between;align-items:center;gap:14px;
    border:1px solid rgba(69,160,232,.4);border-radius:6px;background:rgba(69,160,232,.09);padding:16px 18px;
    font-family:var(--body);font-size:1.03rem;font-weight:600;letter-spacing:0;text-transform:none;color:var(--fog)}
  .est-line b{font-family:var(--disp);font-size:1.5rem;font-weight:800;color:var(--signal-ink)}
  .est-note{margin-top:8px;font-family:var(--body);font-size:.92rem;line-height:1.55;
    letter-spacing:0;text-transform:none;color:var(--fog-dim)}
  .f-submit{display:flex;flex-direction:column;align-items:center;gap:13px;
    border-top:1px solid var(--line);padding-top:28px}
  .f-submit .btn{width:min(360px,100%);justify-content:center;font-family:var(--body);
    font-size:1.1rem;font-weight:700;letter-spacing:.01em;text-transform:none;padding:18px 36px;border-radius:6px}
  .f-note{font-family:var(--body);font-size:.93rem;letter-spacing:0;text-transform:none;
    color:var(--fog-dim);text-align:center;margin:0}
  @media (max-width:860px){.addon-row{grid-template-columns:1fr}.f-date input{max-width:none}}


  /* ---------- entry clicker ---------- */
  /* A one-time door. The lens sits dead and grey until the red button is
     pressed; it fires once, clears the screen, and is removed for good. The
     whole thing is built in JS, so a visitor without JS never meets a door
     they cannot open. */
  .kp-gate{position:fixed;inset:0;z-index:300;display:grid;place-items:center;
    background:#0F1210;opacity:1;
    transition:opacity .6s cubic-bezier(.4,0,.2,1)}
  .kp-gate.is-gone{opacity:0;pointer-events:none}
  .kp-gate-stack{display:flex;flex-direction:column;align-items:center;
    gap:clamp(22px,4vh,38px);padding:24px}
  .kp-gate-lens{position:relative;width:clamp(240px,46vw,420px);aspect-ratio:1;
    transition:transform .55s cubic-bezier(.34,1.3,.5,1)}
  /* the grey belongs to the barrel alone — on the wrapper it drained the
     colour straight back out of the lamp burning inside it */
  .kp-gate-lens img{width:100%;height:100%;display:block;-webkit-user-drag:none;user-select:none;
    filter:grayscale(1) brightness(.46) contrast(.92);transition:filter .55s ease}
  .kp-gate.is-firing .kp-gate-lens img{filter:none}
  /* Light trapped in the glass: a slow RGB wheel sunk into the middle of the
     barrel, masked to a soft disc so it never spills past the iris. Sits
     under the grayscale filter's sibling, so it stays dim until the shot. */
  .kp-gate-lamp{position:absolute;left:50%;top:50%;width:32%;aspect-ratio:1;
    transform:translate(-50%,-50%);border-radius:50%;pointer-events:none;
    background:conic-gradient(from 0deg,
      rgba(255,64,64,.85),rgba(64,255,140,.8),rgba(72,148,255,.85),rgba(255,64,64,.85));
    filter:blur(14px) saturate(1.5);
    -webkit-mask-image:radial-gradient(circle closest-side,#000 38%,transparent 76%);
    mask-image:radial-gradient(circle closest-side,#000 38%,transparent 76%);
    opacity:.34;mix-blend-mode:screen;
    animation:kpGateLamp 11s linear infinite;
    transition:opacity .45s ease,filter .45s ease}
  @keyframes kpGateLamp{to{transform:translate(-50%,-50%) rotate(360deg)}}
  /* the shot: colour floods back, the barrel kicks toward the viewer */
  .kp-gate.is-firing .kp-gate-lens{transform:scale(1.07)}
  .kp-gate.is-firing .kp-gate-lamp{opacity:.9;filter:blur(18px) saturate(1.8)}
  .kp-gate-btn{position:relative;width:46px;height:46px;border-radius:50%;border:0;padding:0;
    cursor:pointer;background:
      radial-gradient(circle at 36% 30%,#FF8A84 0,#E5484D 42%,#8E1D22 100%);
    box-shadow:0 0 0 1px rgba(231,228,218,.16),0 0 22px rgba(229,72,77,.5),
      inset 0 -5px 12px rgba(0,0,0,.45),inset 0 4px 9px rgba(255,255,255,.28);
    animation:kpGateBreathe 2.6s ease-in-out infinite;
    transition:transform .16s ease,box-shadow .3s ease}
  /* a generous invisible hit area — the visible dot stays small */
  .kp-gate-btn::after{content:"";position:absolute;inset:-16px;border-radius:50%}
  .kp-gate-btn:hover{transform:scale(1.06)}
  .kp-gate-btn:active{transform:scale(.94)}
  .kp-gate-btn:focus-visible{outline:2px solid var(--signal);outline-offset:6px}
  .kp-gate.is-firing .kp-gate-btn{transform:scale(.82);animation:none;
    box-shadow:0 0 0 1px rgba(231,228,218,.16),0 0 46px rgba(229,72,77,.85),
      inset 0 -5px 12px rgba(0,0,0,.45)}
  @keyframes kpGateBreathe{
    0%,100%{box-shadow:0 0 0 1px rgba(231,228,218,.16),0 0 18px rgba(229,72,77,.42),
      inset 0 -5px 12px rgba(0,0,0,.45),inset 0 4px 9px rgba(255,255,255,.28)}
    50%{box-shadow:0 0 0 1px rgba(231,228,218,.22),0 0 34px rgba(229,72,77,.72),
      inset 0 -5px 12px rgba(0,0,0,.45),inset 0 4px 9px rgba(255,255,255,.28)}}
  .kp-gate-cue{font-family:var(--mono);font-size:.6875rem;font-weight:700;
    letter-spacing:.22em;text-transform:uppercase;color:rgba(231,228,218,.6);
    transition:opacity .3s ease}
  .kp-gate.is-firing .kp-gate-cue{opacity:0}
  /* The flash belongs to the lens, not the room: a burst that blooms out of
     the glass and dies, rather than whiting out the whole screen. */
  .kp-gate-burst{position:absolute;left:50%;top:50%;width:100%;aspect-ratio:1;
    transform:translate(-50%,-50%) scale(.25);border-radius:50%;
    pointer-events:none;opacity:0;
    background:radial-gradient(circle,rgba(255,255,255,.98) 0%,rgba(255,244,250,.55) 34%,
      rgba(255,255,255,.14) 56%,transparent 72%)}
  .kp-gate.is-firing .kp-gate-burst{animation:kpGateBurst .6s cubic-bezier(.2,.7,.3,1) forwards}
  @keyframes kpGateBurst{
    0%{opacity:0;transform:translate(-50%,-50%) scale(.22)}
    16%{opacity:1;transform:translate(-50%,-50%) scale(.82)}
    100%{opacity:0;transform:translate(-50%,-50%) scale(1.75)}}
  @media (prefers-reduced-motion:reduce){
    .kp-gate,.kp-gate-lens,.kp-gate-btn,.kp-gate-lamp{transition:none}
    .kp-gate-btn,.kp-gate-lamp{animation:none}
    .kp-gate.is-firing .kp-gate-burst{animation:none}}

  /* ---------- aperture intro ---------- */
  .aperture{position:absolute;top:50%;left:50%;z-index:9;
    width:clamp(300px,52svh,500px);aspect-ratio:1;pointer-events:auto;cursor:pointer;
    container-type:inline-size;   /* lets the hint size itself off the lens */
    transform:translate(-50%,-50%);
    /* The lens is a shutter button, so rapid taps are expected input. Without
       this, mobile browsers read tap-tap as double-tap-to-zoom and blow up the
       page. `manipulation` kills only double-tap zoom on the lens — page-wide
       pinch zoom still works, unlike user-scalable=no. The callout/select rules
       stop fast taps from flashing a selection or a long-press menu. */
    touch-action:manipulation;-webkit-touch-callout:none;
    -webkit-user-select:none;user-select:none;
    transition:transform 1.25s cubic-bezier(.6,.05,.18,1),top 1.25s cubic-bezier(.6,.05,.18,1)}
  /* Open state: on wide desktop camera.js computes an exact size + position
     (a big lens on the right, level with the headline). This is only the
     pre-JS fallback / no-JS resting spot — lower-right, larger. */
  .hero.open .aperture{transform:translate(calc(-50% + 21vw),calc(-50% + 9svh)) scale(.85)}
  /* Narrow desktop windows: not enough room to sit beside the headline, so the
     lens centres above the hero text instead. (JS lensAnchor mirrors this.) */
  @media (min-width:861px) and (max-width:1024px){
    .hero.open .aperture{transform:translate(-50%,calc(-50% - 16svh)) scale(.6)}
  }
  .hero.open .ap-img{transition:transform .55s cubic-bezier(.3,.1,.2,1),filter 1.6s ease}
  .hero.open .aperture:hover .ap-img{transform:perspective(900px) rotateX(var(--px,0deg)) rotateY(var(--py,0deg)) rotate(12deg) scale(.95);animation:charge 2.4s cubic-bezier(.4,0,.6,1) forwards}
  @keyframes charge{
    0%{filter:none}
    62%{filter:drop-shadow(0 0 10px rgba(255,244,220,.35)) drop-shadow(0 0 30px rgba(69,160,232,.35))}
    78%{filter:drop-shadow(0 0 18px rgba(255,248,230,.9)) drop-shadow(0 0 55px rgba(69,160,232,.7)) brightness(1.55)}
    100%{filter:drop-shadow(0 0 12px rgba(255,244,220,.5)) drop-shadow(0 0 34px rgba(69,160,232,.45)) brightness(1.05)}
  }
  .ap-img{width:100%;height:100%;display:block;
    transform:rotate(-36deg) scale(1.07);
    filter:grayscale(1) brightness(.5) drop-shadow(0 0 24px rgba(0,0,0,.55));
    transition:transform 1.25s cubic-bezier(.6,.05,.18,1),filter 1.25s ease}
  .hero.open .ap-img{transform:perspective(900px) rotateX(var(--px,0deg)) rotateY(var(--py,0deg));
    filter:drop-shadow(0 16px 28px rgba(0,0,0,.52)) drop-shadow(0 2px 8px rgba(0,0,0,.4)) drop-shadow(0 0 38px rgba(60,140,210,.15))}
  /* Curved front element over the iris: a soft dome catch upper-left, a hard
     thin crescent on the rim, a faint cool counter-catch low-right, and an
     inner vignette that seats the blades into the barrel. Sits above the mech
     copies, below the blink/flash. */
  .ap-glass{position:absolute;inset:21.5%;z-index:2;border-radius:50%;pointer-events:none;
    opacity:0;transition:opacity 1s ease .5s;
    transform:perspective(900px) rotateX(var(--px,0deg)) rotateY(var(--py,0deg));
    background:
      radial-gradient(58% 44% at 33% 26%,rgba(255,255,255,.30),rgba(255,255,255,.05) 55%,transparent 70%),
      radial-gradient(120% 120% at 30% 22%,transparent 56%,rgba(255,255,255,.24) 58.5%,transparent 62%),
      radial-gradient(52% 44% at 70% 82%,rgba(140,200,255,.12),transparent 70%),
      radial-gradient(circle,transparent 54%,rgba(0,0,0,.3) 64%,transparent 71%)}
  .hero.open .ap-glass{opacity:1}
  /* Shot counter in the iris hole (the transparent core is ~22% of the
     graphic). Mono like the nav, sized off the lens itself, riding the same
     tilt vars; the blink (z4) blacks it out during each shot, which reads as
     the counter flipping over. Fades after 30s idle while the scribbled
     invitation returns. */
  .ap-count{position:absolute;top:50%;left:50%;z-index:2;pointer-events:none;
    transform:translate(-50%,-50%) perspective(900px) rotateX(var(--px,0deg)) rotateY(var(--py,0deg));
    text-align:center;font-family:var(--mono);color:#E7E4DA;
    opacity:0;transition:opacity .45s ease;
    text-shadow:0 0 10px rgba(0,0,0,.9),0 1px 3px rgba(0,0,0,.9)}
  .ap-count.on{opacity:1}
  .ap-count b{display:block;font-weight:700;font-size:4.6cqw;letter-spacing:.06em;line-height:1}
  .ap-count i{display:block;margin-top:.5cqw;font-style:normal;font-weight:700;font-size:2.4cqw;
    letter-spacing:.2em;color:#8CCCFF;text-shadow:0 0 8px rgba(69,160,232,.6),0 1px 3px rgba(0,0,0,.9)}
  .ap-count i.hot{color:#FF6A5E;text-shadow:0 0 10px rgba(255,80,60,.7),0 1px 3px rgba(0,0,0,.9)}
  .ap-count b.bump{animation:countBump .3s cubic-bezier(.3,.8,.3,1)}
  @keyframes countBump{0%{transform:scale(1)}40%{transform:scale(1.22)}100%{transform:scale(1)}}
  @media (prefers-reduced-motion:reduce){.ap-count b.bump{animation:none}}
  .ap-cap2{position:absolute;top:50%;left:50%;width:37%;height:37%;
    transform:translate(-50%,-50%);background:#0b0e0b;border-radius:50%;
    transition:transform 1.05s cubic-bezier(.6,.05,.18,1) .18s,opacity .9s ease .18s}
  .hero.open .ap-cap2{transform:translate(-50%,-50%) scale(0);opacity:0}
  /* mechanical life v2: the logo's own parts, separated. Two masked copies of
     the lens art ride above the base image — the ornamental outer ring slowly
     hunts back and forth like a focus ring, and the colored shutter core
     creeps around continuously, snapping a fast 60° on every shot. The band
     between the masks stays put (the base image), so the parts genuinely read
     as independent pieces. Hidden until the lens opens — pre-open the base
     art is rotated and greyed, so moving copies would tear the image. */
  .ap-mech{position:absolute;inset:0;pointer-events:none;opacity:0;transition:opacity .8s ease .5s;
    transform:perspective(900px) rotateX(var(--px,0deg)) rotateY(var(--py,0deg))}
  .hero.open .ap-mech{opacity:1}
  .ap-mech img{position:absolute;inset:0;width:100%;height:100%}
  .ap-ring{-webkit-mask-image:radial-gradient(circle closest-side,transparent 0 62%,#000 66% 100%);
    mask-image:radial-gradient(circle closest-side,transparent 0 62%,#000 66% 100%);
    animation:ringHunt 9s ease-in-out infinite}
  @keyframes ringHunt{0%,100%{transform:rotate(0)}30%{transform:rotate(7deg)}55%{transform:rotate(-5deg)}80%{transform:rotate(3deg)}}
  .ap-core{-webkit-mask-image:radial-gradient(circle closest-side,#000 0 55%,transparent 60%);
    mask-image:radial-gradient(circle closest-side,#000 0 55%,transparent 60%);
    animation:coreCreep 40s linear infinite}
  @keyframes coreCreep{to{transform:rotate(360deg)}}
  /* every shot: the core snaps a blade over; the outer ring recoils the other
     way like a mechanism taking the kick, then resumes its idle hunt */
  .ap-img.cam-press~.ap-mech .ap-core{animation:coreSnap .45s cubic-bezier(.3,.7,.2,1),coreCreep 40s linear infinite .45s}
  .ap-img.cam-press~.ap-mech .ap-ring{animation:ringRecoil .55s cubic-bezier(.25,.9,.3,1.2),ringHunt 9s ease-in-out infinite .55s}
  @keyframes ringRecoil{0%{transform:rotate(0)}30%{transform:rotate(-8deg)}72%{transform:rotate(2.5deg)}100%{transform:rotate(0)}}
  @keyframes coreSnap{0%{transform:rotate(0)}60%{transform:rotate(52deg)}100%{transform:rotate(60deg)}}
  .ap-hint{position:absolute;left:50%;transform:translateX(-50%);bottom:-78px;
    display:flex;flex-direction:column;align-items:center;pointer-events:none;
    animation:hintpulse 2.2s ease-in-out infinite;transition:opacity .5s ease}
  /* little 3D record button: glossy red dome sitting in a dark bezel. The dome
     stays 40px, but ::before adds a much larger invisible tap area around it so
     it's easy to hit; it's the real click target that opens the lens. */
  .ap-rec{position:relative;width:40px;height:40px;border-radius:50%;pointer-events:auto;cursor:pointer;
    background:radial-gradient(circle at 34% 28%,#ff9d94 0 10%,#f4443a 36%,#c81e16 64%,#7c0e09 100%);
    border:2px solid rgba(18,6,4,.9);
    box-shadow:0 0 0 5px #171b16,0 0 0 6px rgba(231,228,218,.16),
      0 6px 14px rgba(0,0,0,.6),0 0 22px rgba(255,64,52,.5),
      inset 0 2px 3px rgba(255,255,255,.4),inset 0 -4px 7px rgba(70,0,0,.6)}
  .ap-rec::before{content:"";position:absolute;inset:-42px;border-radius:50%}
  /* Slow beacon sweep: a single WOBBLY glowing sonar ring expands from the red
     button over ~8s. Where its rippling edge grinds across the text and frames,
     it throws fire-on-metal sparks — only along the exact contact line, tracing
     each element's edges progressively as the ring rolls through. Canvas below. */
  .sonar-canvas{position:fixed;inset:0;z-index:58;pointer-events:none;mix-blend-mode:overlay}
  @media (prefers-reduced-motion:reduce){.sonar-canvas{display:none}}
  @keyframes hintpulse{0%,100%{opacity:1;transform:translateX(-50%) translateY(0)}50%{opacity:.7;transform:translateX(-50%) translateY(3px)}}
  /* idle cue: appears beside the rec button 5s after load if nothing was
     clicked (JS adds .cue-on); arrow points at the button */
  .ap-cue{position:absolute;left:calc(50% + 32px);top:50%;transform:translateY(-50%) translateX(-8px);
    display:flex;align-items:center;gap:7px;white-space:nowrap;opacity:0;pointer-events:none;
    transition:opacity .7s ease,transform .7s ease}
  .ap-hint.cue-on .ap-cue{opacity:1;transform:translateY(-50%)}
  .ap-cue svg{width:34px;height:14px;overflow:visible}
  .ap-cue i{font-style:normal;font-family:var(--mono);font-size:.625rem;letter-spacing:.14em;text-transform:uppercase;
    color:rgba(231,228,218,.85);font-weight:300;text-shadow:0 1px 5px rgba(0,0,0,.7)}
  /* mini scribbled invitation on the glass — only once the camera phase is
     live (JS sets "click" or "tap" by pointer type) */
  .ap-scribble{position:absolute;top:50%;left:50%;z-index:2;transform:translate(-50%,-50%) rotate(-7deg);
    pointer-events:none;font-family:'Segoe Script','Bradley Hand','Savoye LET','Comic Sans MS',cursive;
    font-size:clamp(.6rem,2vh,.8rem);   /* fallback where cqw is unsupported */
    font-size:5cqw;
    letter-spacing:.1em;text-transform:uppercase;transform-origin:center;white-space:nowrap;
    color:#E5484D; /* rec red, with a static camera-sensor RGB chromatic shimmer */
    text-shadow:-.6px 0 0 rgba(255,64,64,.55),.7px 0 0 rgba(64,132,255,.5),0 .5px 0 rgba(70,235,150,.32),0 1px 8px rgba(0,0,0,.72);
    opacity:0;visibility:hidden;transition:opacity .5s ease .9s}
  /* static (no wobble) — just a gentle 46-66% opacity breathe, never full */
  .hero.open .ap-scribble{opacity:.58;visibility:visible;animation:sensorBreath 3.6s ease-in-out infinite}
  .hero.open .ap-scribble.done{animation:none}
  @keyframes sensorBreath{0%,100%{opacity:.46}50%{opacity:.66}}
  @media (prefers-reduced-motion:reduce){.hero.open .ap-scribble{animation:none;opacity:.56}}
  /* once the lens has been used, the invitation leaves for good */
  .hero.open .ap-scribble.done{opacity:0;visibility:hidden;transition:opacity .3s ease,visibility 0s .3s}
  .hero.open .ap-hint{opacity:0;animation:none;visibility:hidden;transition:opacity .5s ease,visibility 0s .5s}
  .hero .footage{filter:grayscale(.85) brightness(.72);transition:filter 1.4s ease .1s}
  .hero.open .footage{filter:none}
  .hero .hud{opacity:0;transition:opacity .9s ease .65s}
  .hero.open .hud{opacity:1}
  .hero-inner{opacity:0;transform:translateY(26px);pointer-events:none;
    transition:opacity .95s ease .5s,transform .95s cubic-bezier(.2,.7,.2,1) .5s}
  .hero.open .hero-inner{opacity:1;transform:none}
  /* .cam-stack: desktop = invisible full-bleed layer the JS-positioned counter
     lives in (same coordinates as before). Mobile = a real flow column. */
  .cam-stack{position:absolute;inset:0;pointer-events:none;z-index:6}
  .lens-slot{display:none}
  @media (max-width:860px){
    /* Closed (intro) lens: center on the visible screen, not the hero — the
       flow-based hero is taller than the viewport, so 50% of it sits too low.
       The open state overrides top with --lens-y, so only the intro moves. */
    .aperture{width:clamp(210px,58vw,320px);top:min(50svh,50%)}
    /* min() not clamp(): the old 2.45rem floor ignored viewport width, so a larger
       accessibility text size blew the headline up to 4 lines. Capping by 10vw keeps
       it to 2 lines at any text size — identical size on a default phone. */
    h1.hl{font-size:min(2.7rem,10vw)}
    .sub{max-width:none;margin-top:16px}
    .hs-row{gap:12px;padding:7px 0}
    .hs-v{font-size:.72rem}
    .cta-row{margin-top:22px;gap:10px;flex-wrap:nowrap}
    /* equal halves: two chips of different widths under a centred lens was
       most of what read as unorganised */
    .cta-row .btn{flex:1 1 0;justify-content:center;text-align:center}
    .btn{padding:14px 12px;font-size:0.7188rem}
    .hero-inner{padding-bottom:10px;margin-top:auto}
/* FLOW-BASED mobile hero: the hero is a column — counter, then a slot that
   reserves the lens's real footprint, then (auto gap) the copy. Because every
   piece occupies real space, a larger accessibility text size pushes content
   DOWN the page instead of colliding it. camera.js measures .lens-slot and
   sets --lens-y to its centre, so the absolutely-positioned (animatable) lens
   lands exactly in the reserved hole. --lens-y here is only the pre-JS fallback. */
    .hero{--lens-y:310px;--lens-scale:1;padding-top:104px;flex-direction:column;align-items:stretch}
    /* the lens drops down the hero so a developed print has room to rise
       above it without colliding with the REC strip */
    .cam-stack{position:static;inset:auto;display:flex;flex-direction:column;align-items:center;gap:12px;margin-top:clamp(76px,24vw,132px);margin-bottom:20px}
    .lens-slot{display:block;width:100%;height:clamp(210px,58vw,320px)}
    /* relative + high z-index lifts the stat row above the absolutely-
       positioned lens, which otherwise sits on top and eats the taps */
.hero.open .aperture{top:var(--lens-y);transform:translate(-50%,-50%) scale(var(--lens-scale,.29))}}
  @media (prefers-reduced-motion:reduce){
    .ap-img,.ap-cap2,.hero .footage,.hero .hud,.hero-inner,.ap-hint,.aperture{transition:none}
    .footage-vid{display:none}
  }




  /* ---------- footer ---------- */
  /* Footer sits in deep water, bookending the header. Full-bleed the same way
     the booking band does, and re-declare the dark tokens so every
     token-driven rule inside keeps working. It was one flat row of eight mono
     links; now it is a brand block, two named columns, and a bottom bar. */
  footer{position:relative;border-top:1px solid rgba(120,180,225,.18);
    padding:clamp(52px,8svh,88px) clamp(24px,4vw,54px) clamp(26px,4svh,38px);
    max-width:1360px;margin:0 auto;
    display:grid;grid-template-columns:minmax(0,1.6fr) repeat(2,minmax(0,1fr));
    gap:clamp(30px,5vw,72px);align-items:start;
    --fog:#E9F1F7;--fog-dim:#8FB4CF;--line:rgba(120,180,225,.2);--line-2:rgba(120,180,225,.12);
    color:var(--fog)}
  footer::before{content:"";position:absolute;left:50%;top:0;bottom:0;width:100vw;
    transform:translateX(-50%);z-index:0;pointer-events:none;
    background:linear-gradient(180deg,#0B2138 0%,#061627 60%,#040F1C 100%)}
  footer > *{position:relative;z-index:1}

  .foot-brand{max-width:38ch}
  .foot-mark{display:inline-flex;align-items:center;gap:11px;font-family:var(--mono);
    font-size:0.6875rem;font-weight:700;letter-spacing:.18em;text-transform:uppercase;
    line-height:1.35;color:var(--fog)}
  .foot-mark img{width:38px;height:38px;flex:none}
  .foot-blurb{margin-top:16px;font-size:.92rem;line-height:1.6;color:var(--fog-dim);text-wrap:pretty}
  .foot-mail{display:inline-block;margin-top:16px;font-size:1rem;color:var(--fog);
    border-bottom:1px solid rgba(120,180,225,.4);padding-bottom:2px;transition:color .2s,border-color .2s}
  .foot-mail:hover{color:#8CCCFF;border-color:#8CCCFF}
  .foot-status{display:flex;align-items:center;gap:9px;width:fit-content;margin-top:20px;
    font-family:var(--mono);font-size:0.5625rem;letter-spacing:.16em;text-transform:uppercase;
    color:#9FD4A8;border:1px solid rgba(159,212,168,.32);border-radius:999px;padding:6px 13px}
  .fs-lamp{width:7px;height:7px;border-radius:50%;background:#6FD684;flex:none;
    box-shadow:0 0 8px rgba(111,214,132,.9);animation:footLamp 2.4s steps(1) infinite}
  @keyframes footLamp{50%{opacity:.3}}

  .foot-col{display:flex;flex-direction:column;align-items:flex-start;gap:13px;min-width:0}
  .foot-col h2{margin:0 0 4px;font-family:var(--mono);font-weight:400;font-size:0.5rem;
    letter-spacing:.3em;text-transform:uppercase;color:#5E93BC}
  .foot-col a{font-family:var(--mono);font-size:0.6875rem;letter-spacing:.14em;
    text-transform:uppercase;color:var(--fog-dim);width:fit-content;opacity:1;
    transition:color .2s ease,transform .2s ease}
  .foot-col a:hover{color:#8CCCFF;transform:translateX(3px)}

  /* the back-to-top button is fixed bottom-right and lands on this row when
     the footer is in view, so the row keeps a lane clear for it */

  .foot-fine{grid-column:1/-1;margin-top:clamp(28px,4svh,46px);padding-top:20px;
    padding-right:62px;border-top:1px solid var(--line-2);
    font-family:var(--mono);font-size:0.5625rem;letter-spacing:.12em;text-transform:uppercase;
    color:#6E93B0;display:flex;justify-content:space-between;flex-wrap:wrap;gap:10px}

  @media(max-width:760px){
    footer{grid-template-columns:1fr 1fr;gap:34px 24px}
    .foot-brand{grid-column:1/-1;max-width:none}
  }
  @media (prefers-reduced-motion:reduce){.fs-lamp{animation:none}.foot-col a:hover{transform:none}}

  /* ---------- reveal ---------- */
  .reveal{opacity:0;transform:translateY(26px);transition:opacity .7s ease,transform .7s cubic-bezier(.2,.7,.2,1)}
  .reveal.in{opacity:1;transform:none}

  /* Shutter flash: scoped to the lens, not the screen — a hot white burst
     inside the aperture circle, then a slower chromatic mist puff around it.
     Both live inside .aperture so they track the lens wherever it animates.
     --mist-hue is randomized per shot by camera.js. */
  /* Mirror blackout: the iris goes dark for a beat BEFORE the light reads --
     the blink sits above the flash, so the flash blooms out of the dark. */
  .ap-blink{position:absolute;inset:5%;z-index:4;border-radius:50%;pointer-events:none;opacity:0;
    background:radial-gradient(circle,#05070a 0 58%,rgba(5,7,10,.6) 74%,transparent 82%)}
  .ap-img.cam-press~.ap-blink{animation:apBlink .32s cubic-bezier(.6,0,.3,1)}
  @keyframes apBlink{0%{opacity:0}18%{opacity:.96}52%{opacity:.9}100%{opacity:0}}
  /* pressure wave off the rim as the shot fires */
  .ap-wave{position:absolute;inset:2%;z-index:2;border-radius:50%;pointer-events:none;opacity:0;
    border:2px solid rgba(160,215,255,.55);box-shadow:0 0 18px rgba(120,200,255,.35),inset 0 0 14px rgba(120,200,255,.25)}
  .ap-img.cam-press~.ap-wave{animation:apWave .6s cubic-bezier(.2,.7,.3,1) .1s}
  @keyframes apWave{0%{opacity:0;transform:scale(.9)}22%{opacity:.8}100%{opacity:0;transform:scale(1.28)}}
  .ap-flash{position:absolute;inset:6%;z-index:3;border-radius:50%;pointer-events:none;opacity:0;
    background:radial-gradient(circle,#fff 0 26%,rgba(255,255,255,.55) 52%,rgba(255,255,255,0) 72%)}
  .ap-flash.snap{animation:snap .5s ease-out .07s}
  @keyframes snap{0%{opacity:0}10%{opacity:1}26%{opacity:.7}100%{opacity:0}}
  .ap-mist{position:absolute;inset:-22%;z-index:2;border-radius:50%;pointer-events:none;opacity:0;
    background:
      radial-gradient(34% 34% at 30% 38%,rgba(255,90,150,.5),transparent 70%),
      radial-gradient(30% 30% at 68% 30%,rgba(80,200,255,.45),transparent 70%),
      radial-gradient(36% 36% at 62% 68%,rgba(255,190,80,.4),transparent 70%),
      radial-gradient(30% 30% at 36% 70%,rgba(150,120,255,.45),transparent 70%);
    filter:blur(18px) hue-rotate(var(--mist-hue,0deg)) saturate(1.4)}
  .ap-mist.puff{animation:mistPuff 1.5s ease-out}
  @keyframes mistPuff{
    0%{opacity:0;transform:scale(.55) rotate(0)}
    18%{opacity:.85}
    100%{opacity:0;transform:scale(1.3) rotate(24deg)}}
  /* ---------- interactive camera (hero lens = shutter) ---------- */
  /* Stat row under the lens: three white icon+number stats (trophy badges,
     camera shots, globe community). No chip background — icons and numbers
     glow. camera.js pins the row beneath the lens, scales its font with the
     lens size (via inline font-size), and tracks the lens wherever it sits. */
  /* Gold = tap/click me. Faintly visible + always clickable so the overlay is
     reachable anytime; it flashes to full on a shot or on hover. z-index sits above
     the headline so nothing intercepts the click on desktop. */
  /* Visible and clickable for the whole camera phase (once the lens is open),
     so the trophy / shot / community chips can always be tapped to open their
     popups. pointer-events inherits down to the three chips. */
  /* camera print — base structure (frame chrome is per-style below) */
  /* z-index sits BELOW the lens (aperture is z-index:5) so a developed photo
     emerges from behind the clicker and never covers it — while sitting ABOVE
     the hero copy (z-index 6) so a developed frame is never hidden by the
     headline. It fades out on its own after IDLE_FADE_MS. */
  /* Every frame style shares one outer box (fixed width + 3:4 ratio) and the
     photo flexes to fill whatever the mat leaves, so a polaroid, a slide and a
     negative all occupy exactly the same footprint. Tap a live print to open it. */
  .cam-print{position:absolute;z-index:8;pointer-events:none;opacity:0;
    width:clamp(122px,11.5vw,148px);aspect-ratio:3/4;
    display:flex;flex-direction:column;
    transform:translateX(-50%) rotate(var(--tilt,0deg));transform-origin:top center;
    /* low, dim glow so the print lifts off the footage without looking lit up */
    filter:drop-shadow(0 0 9px rgba(231,228,218,.13)) drop-shadow(0 0 24px rgba(180,215,255,.10));
    backface-visibility:hidden;-webkit-backface-visibility:hidden;
    transition:opacity .6s ease}
  .cam-print.live{opacity:1;pointer-events:auto;cursor:zoom-in}
  .cam-print.idle{opacity:0}
  .cam-frame{position:relative;overflow:hidden;background:#000;line-height:0;flex:1 1 auto;min-height:0}
  .cam-photo{width:100%;height:100%;object-fit:cover;display:block;background:var(--panel)}
  .cam-lcd{display:flex;justify-content:space-between;align-items:baseline;gap:8px}
  .cam-meta{font-family:var(--mono);font-size:0.5312rem;letter-spacing:.08em;text-transform:uppercase;
    color:var(--fog-dim);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .cam-sim{font-family:var(--mono);font-size:0.5312rem;letter-spacing:.14em;text-transform:uppercase;
    font-weight:600;white-space:nowrap;flex:none}
  .cam-tag{position:absolute;top:0;right:0;z-index:3;font-family:var(--mono);font-size:0.5rem;
    letter-spacing:.12em;text-transform:uppercase;padding:4px 7px}
  .cam-print.t-secret{outline:2px solid rgba(212,175,55,.85);outline-offset:3px}
  /* Digital Preview */
  .cam-print.f-digital{background:#0c0f0c;border:1px solid var(--line);padding:8px;box-shadow:0 18px 44px rgba(0,0,0,.55)}
  .cam-print.f-digital .cam-lcd{padding:8px 2px 2px}
  .cam-print.f-digital .cam-sim{color:var(--signal)}
  .cam-print.f-digital .cam-tag{top:8px;right:8px;color:var(--fog-dim);background:rgba(12,15,12,.72)}
  /* Polaroid */
  .cam-print.f-polaroid{background:#f4efe4;padding:11px 11px 42px;border-radius:2px;box-shadow:0 22px 46px rgba(0,0,0,.55)}
  .cam-print.f-polaroid .cam-lcd{position:absolute;left:0;right:0;bottom:13px;justify-content:center;padding:0 12px}
  .cam-print.f-polaroid .cam-meta{display:none}
  .cam-print.f-polaroid .cam-sim{color:#403c33;font-weight:400;letter-spacing:.1em;font-size:0.625rem}
  .cam-print.f-polaroid .cam-tag{top:11px;right:11px;color:#f4efe4;background:rgba(18,20,16,.55)}
  /* Film Negative */
  .cam-print.f-negative{background:#0a0906;padding:17px 12px;box-shadow:0 18px 42px rgba(0,0,0,.6)}
  .cam-print.f-negative::before,.cam-print.f-negative::after{content:"";position:absolute;left:11px;right:11px;
    height:6px;background:repeating-linear-gradient(90deg,#b9ad86 0 6px,transparent 6px 15px)}
  .cam-print.f-negative::before{top:5px}
  .cam-print.f-negative::after{bottom:5px}
  .cam-print.f-negative .cam-frame{border:1px solid #241f16}
  .cam-print.f-negative .cam-lcd{padding:7px 2px 0}
  .cam-print.f-negative .cam-sim{color:#E8A24A}
  .cam-print.f-negative .cam-meta{color:#7a6a52}
  .cam-print.f-negative .cam-tag{top:17px;right:12px;color:#E8A24A;background:rgba(10,9,6,.72)}
  /* Contact Sheet */
  .cam-print.f-contact{background:#121410;border:1px solid var(--line);padding:9px;box-shadow:0 18px 42px rgba(0,0,0,.5)}
  .cam-print.f-contact .cam-frame{border:2px solid #e7e4da}
  .cam-print.f-contact .cam-frame::after{content:"";position:absolute;left:6%;top:5%;width:88%;height:90%;
    border:2.5px solid rgba(229,72,77,.85);border-radius:48%;transform:rotate(-4deg)}
  .cam-print.f-contact .cam-lcd{padding:7px 2px 0}
  .cam-print.f-contact .cam-sim{color:#E5484D}
  .cam-print.f-contact .cam-meta{color:var(--fog-dim)}
  .cam-print.f-contact .cam-tag{top:9px;right:9px;color:#E5484D;background:rgba(18,20,16,.72)}
  /* Vintage Slide */
  .cam-print.f-slide{background:#e7e1d2;padding:27px 14px 14px;border-radius:3px;box-shadow:0 22px 46px rgba(0,0,0,.55)}
  .cam-print.f-slide::before{content:"KODACHROME 64";position:absolute;top:9px;left:15px;
    font-family:var(--mono);font-size:0.5rem;letter-spacing:.1em;font-weight:700;color:#8a3c2c}
  .cam-print.f-slide .cam-frame{border:1px solid rgba(0,0,0,.28)}
  .cam-print.f-slide .cam-lcd{padding:8px 2px 0}
  .cam-print.f-slide .cam-meta{color:#6b6656}
  .cam-print.f-slide .cam-sim{color:#3a3730}
  /* tag sits on the photo, below the 27px mat — "KODACHROME 64" owns the mat
     line, and on narrow prints the two collided when they shared it */
  .cam-print.f-slide .cam-tag{top:31px;right:16px;color:#f4efe4;background:rgba(18,20,16,.55)}
  /* tapped-print lightbox: the frame opens full-size with its story */
  .cam-lb{position:fixed;inset:0;z-index:140;display:flex;align-items:center;justify-content:center;
    padding:clamp(14px,4vh,40px) clamp(14px,4vw,32px);opacity:0;pointer-events:none;transition:opacity .3s ease}
  .cam-lb.on{opacity:1;pointer-events:auto}
  .cam-lb-veil{position:absolute;inset:0;background:rgba(6,8,6,.86);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px)}
  /* A print on a mat. The old card forced every photo into a full-width
     contain box over near-black, so portraits sat between two dark slabs.
     Now the photo keeps its own shape on a clean mat: the card hugs the
     image, the image hugs its ratio. */
  .cam-lb-card{position:relative;width:min(560px,100%);max-height:88svh;overflow:auto;
    background:linear-gradient(172deg,#FDFEFF,#EFF4F9 80%);
    border:1px solid rgba(120,180,225,.28);border-radius:12px;
    padding:clamp(14px,2.6vw,22px) clamp(14px,2.6vw,22px) 16px;
    box-shadow:0 30px 80px rgba(2,10,20,.72),inset 0 1px 0 rgba(255,255,255,.85);
    transform:translateY(28px) rotate(.5deg) scale(.985);
    transition:transform .38s cubic-bezier(.16,.84,.3,1)}
  .cam-lb.on .cam-lb-card{transform:none}
  .cam-lb-img{display:block;width:auto;max-width:100%;height:auto;max-height:60svh;
    margin:0 auto;border-radius:3px;
    box-shadow:0 1px 0 rgba(255,255,255,.9),0 10px 28px rgba(10,32,56,.28),0 0 0 1px rgba(10,32,56,.12)}
  .cam-lb-card figcaption{padding:14px 4px 2px;border-top:1px solid rgba(10,32,56,.1);margin-top:16px;
    display:grid;grid-template-columns:1fr auto;column-gap:12px;align-items:start}
  .cam-lb-kind{grid-column:2;grid-row:1;justify-self:end;font-family:var(--mono);font-size:.5rem;
    letter-spacing:.18em;white-space:nowrap;
    text-transform:uppercase;color:var(--signal-ink);border:1px solid rgba(69,160,232,.4);
    border-radius:999px;padding:4px 10px}
  .cam-lb-card.secret .cam-lb-kind{color:#8a6d1c;border-color:rgba(180,145,40,.55);
    background:linear-gradient(160deg,rgba(212,175,55,.14),rgba(212,175,55,.04))}
  .cam-lb-title{grid-column:1;grid-row:1;font-family:var(--disp);font-weight:800;font-size:1.12rem;
    text-transform:uppercase;letter-spacing:-.01em;margin:0;line-height:1.15}
  .cam-lb-note{grid-column:1/-1;grid-row:2;color:var(--fog-dim);font-size:.9rem;line-height:1.55;margin-top:6px}
  /* Matches .rev-x on the other overlays. It carried a dark chip and a light-
     theme dark ink glyph, so the close sat at 1.24:1 on its own background --
     a dark circle with a barely-there x, on a light card. */
  .cam-lb-x{position:absolute;top:10px;right:10px;width:32px;height:32px;border-radius:50%;
    border:1px solid var(--line);background:transparent;color:var(--fog);
    font-size:1rem;line-height:1;cursor:pointer;z-index:2;transition:border-color .2s,color .2s}
  .cam-lb-x:hover{border-color:var(--signal);color:var(--signal)}
  @media (prefers-reduced-motion:reduce){.cam-lb,.cam-lb-card{transition:none}}
  /* reveal / exit */
  .cam-print.in{animation:camReveal .3s cubic-bezier(.2,.7,.2,1)}
  .cam-print.out{animation:camExit .22s ease-in forwards}
  @keyframes camReveal{0%{opacity:0;transform:translateX(-50%) translateY(16px) scale(.96) rotate(var(--tilt,0deg))}
    100%{opacity:1;transform:translateX(-50%) translateY(0) scale(1) rotate(var(--tilt,0deg))}}
  @keyframes camExit{100%{opacity:0;transform:translateX(calc(-50% + 52px)) rotate(calc(var(--tilt,0deg) + 3deg))}}
  /* the badges stat opens the badge book; the personal counter opens the
     shot-count popup — both clickable */
  /* shot-count popup: your total + the community total */
  .cam-bsec{font-family:var(--mono);font-size:0.5625rem;font-weight:700;letter-spacing:.24em;text-transform:uppercase;
    color:#9aa08e;padding:20px 22px 2px}
  .cam-dgrid{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;padding:12px 22px 24px}
  @media (max-width:460px){.cam-bgrid,.cam-dgrid{grid-template-columns:repeat(2,1fr)}}
  @media (prefers-reduced-motion:reduce){.cam-ach.in,.cam-ach.out{animation:none}}
  .ap-img.cam-press{animation:camPress .34s cubic-bezier(.3,.7,.3,1)}
  @keyframes camPress{0%{transform:perspective(900px) rotateX(var(--px,0deg)) rotateY(var(--py,0deg)) scale(1)}
    30%{transform:perspective(900px) rotateX(var(--px,0deg)) rotateY(var(--py,0deg)) scale(.935) translateY(1.2%)}
    68%{transform:perspective(900px) rotateX(var(--px,0deg)) rotateY(var(--py,0deg)) scale(1.014)}
    100%{transform:perspective(900px) rotateX(var(--px,0deg)) rotateY(var(--py,0deg)) scale(1)}}
  /* rare "light leak" event + golden whole-roll bloom */
  .cam-leak{position:absolute;inset:0;z-index:8;pointer-events:none;opacity:0;mix-blend-mode:screen;
    background:linear-gradient(115deg,transparent 38%,rgba(255,150,70,.55) 50%,rgba(255,90,60,.32) 58%,transparent 70%);
    background-size:300% 100%;background-position:120% 0}
  .cam-leak.run{animation:camLeak 1.1s ease-out}
  @keyframes camLeak{0%{opacity:0;background-position:120% 0}15%{opacity:.9}100%{opacity:0;background-position:-20% 0}}
  .cam-leak.gold{background:radial-gradient(circle at 68% 46%,rgba(212,175,55,.6),rgba(212,175,55,.14) 42%,transparent 72%);
    background-size:100% 100%;background-position:center}
  .cam-leak.gold.run{animation:camGold 1.7s ease-out}
  @keyframes camGold{0%{opacity:0}22%{opacity:1}100%{opacity:0}}
  @media (max-width:860px){
    .cam-print{width:clamp(118px,28vw,136px)}
  }
  @media (prefers-reduced-motion:reduce){
    .cam-print.in,.cam-print.out,.ap-img.cam-press,.cam-leak.run,
    .ap-img.cam-press~.ap-blink,.ap-img.cam-press~.ap-wave,
    .ap-img.cam-press~.ap-mech .ap-ring{animation:none}
    .cam-print{transition:none}
  }


  /* Headshots card: face-wall cover. All rail cards share one fixed size now,
     so a single top-anchored cover works at every breakpoint. */
  .thumb.t-hs{background-image:url('/atria-headshots/v2/cover-768.webp');background-size:cover;background-position:top}
  @media (max-width:860px){
    /* rate cards get tighter on phones; they're fine as-is on desktop */
    .tier{padding:16px 15px;gap:10px;border-radius:4px}
    .tier.hot,.tier.tagged{padding-top:36px}
    .t-name{font-size:1rem}
    .t-price{font-size:1.5rem}
    .tier li{font-size:.8rem;padding-left:14px}
    .tier ul{gap:5px}
    .t-choose{font-size:0.625rem;padding:9px 11px}
    .t-addon{font-size:0.5625rem;padding:6px 8px}
    .t-badge{font-size:0.5625rem;padding:3px 8px}
    /* Mobile keeps the same three tabs as desktop, centred, and drops the
       wordmark/logo entirely — the homepage doesn't need a link to itself. */
    header{justify-content:center;padding-left:16px;padding-right:16px}
    .wordmark{display:none}
    nav{display:flex;gap:14px;justify-content:center;align-items:center}
    nav a{white-space:nowrap}
    /* the tap-target enlarger above (padding 14 / margin -14) is for text
       links; on a fixed 34px chip it crushes the content box and shoves the
       icon off-centre, so the chip opts out -- it IS its own tap target */
    .nav-mail{width:34px;height:34px;margin:0;padding:0;display:grid;place-items:center}
    .hud .lens,.hud .geo{display:none}
    /* phones: wrap rather than ellipsize -- the wider mono was clipping the
       tail of every note behind the ellipsis */
    .sec-note{margin-left:0;text-align:left;width:100%;white-space:normal}
  }
  @media (prefers-reduced-motion:reduce){
    *{animation:none!important;scroll-behavior:auto!important}
    .reveal{opacity:1;transform:none}
    /* the marquee stops with all animation, so let those users scroll the
       gallery by hand instead */
    .work-rail{overflow-x:auto;-webkit-mask-image:none;mask-image:none}
  }

  /* mobile: prevent iOS toolbar-toggle repaint glitch (drop fixed mix-blend layers) */
  @media (max-width:760px){
    header{mix-blend-mode:normal;padding-top:20px;padding-bottom:26px}
    body::after{display:none}
  }
  /* summary is keyboard-focusable but was missing here, so every <details>
   accordion — the FAQ blocks, the rates drawer, the form's optional tail —
   had no visible focus ring. */
  a:focus-visible,button:focus-visible,summary:focus-visible,[tabindex]:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible{outline:2px solid var(--signal);outline-offset:3px}
  /* iPhone notch / Dynamic Island: let the page paint edge-to-edge but keep
     fixed chrome and content inside the safe area (matters in landscape). */
  @supports(padding:max(0px)){
    header{padding-left:max(clamp(24px,4vw,54px),env(safe-area-inset-left));padding-right:max(clamp(24px,4vw,54px),env(safe-area-inset-right))}
  }
  @supports(padding:max(0px)){
    .hero-inner{padding-left:max(clamp(24px,4vw,54px),env(safe-area-inset-left));padding-right:max(clamp(24px,4vw,54px),env(safe-area-inset-right))}
  }
  @media(max-width:860px){
    nav a{display:inline-block;padding:14px 6px;margin:-14px -2px}
    nav a[href="#work"]{display:none}
    .wordmark{padding:14px 10px;margin:-14px -10px}
    .foot-links a,.arch a{display:inline-block;padding:12px 8px;margin:-12px -4px}
  }

/* Links from the rates section out to the per-service pages. The tabbed cards
   below stay as the quick comparison; these go to the full story. */
.svc-links{display:flex;flex-wrap:wrap;align-items:center;gap:9px 12px;margin:-6px 0 26px}
.svc-links .svl-k{font-family:var(--mono);font-size:.5938rem;font-weight:700;letter-spacing:.2em;
  text-transform:uppercase;color:var(--fog-dim)}
.svc-links a{font-family:var(--mono);font-size:.6875rem;letter-spacing:.1em;text-transform:uppercase;
  color:var(--fog);text-decoration:none;padding:9px 13px;border:1px solid var(--line-2);
  background:var(--panel);transition:border-color .18s ease,color .18s ease,transform .18s ease}
.svc-links a:hover{border-color:var(--signal-ink);color:var(--signal-ink);transform:translateY(-1px)}
.svc-links a.svl-all{border-color:var(--signal-ink);color:var(--signal-ink)}
@media(max-width:620px){.svc-links{gap:7px}.svc-links a{font-size:.625rem;padding:8px 10px}}

/* Adding "Services" pushed the phone header past the viewport. Rates is the
   redundant one now — /services is the rates hub — so it goes on small screens,
   and the remaining links tighten up to buy the rest of the room. */
@media (max-width:860px){
  header{padding-left:16px;padding-right:16px}
  nav{gap:10px}
  nav a{font-size:0.625rem;letter-spacing:.06em;padding-left:5px;padding-right:5px;
    margin-left:-2px;margin-right:-2px}
  nav a[href="#pricing"],nav a[href="/#pricing"]{display:none}
}
