/* ==========================================================================
   Easy Buy Development Ltd — 2026 redesign
   Concept: the page runs on a 24-hour cycle. The hero is night (when the
   system works alone), the body is day (when you work), the closing CTA
   returns to night. Brand green is treated as a light source: it only
   carries meaning on dark surfaces, because #A4D233 on paper is 1.6:1.
   ========================================================================== */

:root{
  /* --- Brand (品牌規格 2026-07-30) ------------------------------------- */
  --lime:#A4D233;              /* brand green — fills and light, never text on paper */
  /* The menu green. White on #A4D233 is 1.77:1 — the thin cart lines and the
     small caps in the logo simply vanish. This is the same hue two steps down,
     where white reaches 4.8:1 and the mark still reads as the brand. */
  --menu:#5C7D1A;
  --lime-lift:#B8E04B;         /* hover / highlight */
  --lime-text:#41590F;         /* 7.2:1 on paper — the green you may set type in */

  /* --- The vertical ramp -----------------------------------------------
     The page's y-axis is time, so the background is one continuous descent
     from deep night down through dawn into day and back to night. Each band
     starts on the colour the band above it finished on, which is why there
     are four night steps rather than one flat fill. */
  --night-0:#0C0908;           /* top of the page, deepest */
  --night-1:#13100D;           /* = --ink */
  --night-2:#1D1814;
  --night-3:#28211B;           /* the last step before dawn */

  /* --- Night ----------------------------------------------------------- */
  --ink:#13100D;               /* page night — warm, not green */
  --ink-2:#1D1814;             /* raised band */
  --card:#28211B;              /* card on night */
  --on-ink:#EDEAE4;            /* warm off-white */
  --on-ink-2:#B3ABA0;          /* secondary on night */
  /* 5.4:1 on flat --ink, but only 4.3:1 on --night-3 (the lightest night step)
     — and the pointer glow lifts those surfaces further. Brightened so the
     dimmest text keeps headroom everywhere on the ramp, glow included. */
  --on-ink-3:#9B9288;
  --line-ink:rgba(237,234,228,.16);

  /* --- Day ------------------------------------------------------------- */
  --paper:#F3F5EC;
  --paper-2:#FFFFFF;
  --on-paper:#12180E;          /* 17.3:1 */
  --on-paper-2:#3D4737;        /* 9.6:1 */
  --on-paper-3:#5D6A57;        /* 5.2:1 */
  --line:rgba(18,24,14,.14);
  --line-2:rgba(18,24,14,.07);

  /* --- Feedback + focus ------------------------------------------------ */
  --danger:#A32217;
  --danger-bg:#FCECEA;
  --focus:#1256A0;
  --focus-on-ink:#CFE88A;

  /* --- Type ------------------------------------------------------------ */
  --display:"Poppins","Noto Sans TC","PingFang HK","Microsoft JhengHei",sans-serif;
  --body:"Noto Sans TC","Poppins","PingFang HK","Microsoft JhengHei",sans-serif;
  --mono:"IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,monospace;

  /* Type scale — 1.25 major third, fluid */
  --t-xs:.75rem;  --t-sm:.875rem; --t-base:1.0625rem;
  --t-lg:clamp(1.125rem,.9rem + .7vw,1.3125rem);
  --t-xl:clamp(1.4rem,1.1rem + 1.1vw,1.75rem);
  --t-2xl:clamp(1.75rem,1.3rem + 2vw,2.5rem);
  --t-3xl:clamp(2.1rem,1.4rem + 3.2vw,3.6rem);
  --t-4xl:clamp(2.6rem,1.5rem + 4.6vw,4.6rem);

  /* --- Space (8px base) ------------------------------------------------ */
  --s1:.5rem; --s2:1rem; --s3:1.5rem; --s4:2rem;
  --s5:3rem;  --s6:4.5rem; --s7:6rem;   --s8:7.5rem;

  --max:1240px;
  --gutter:clamp(20px,4vw,48px);
  --r:14px; --r-lg:22px;
  --tap:44px;
  --header-h:74px;             /* JS keeps this in sync with the real header */
  --ease:cubic-bezier(.2,.75,.3,1);
}

/* ==========================================================================
   Base
   ========================================================================== */
*,*::before,*::after{box-sizing:border-box}
html{
  -webkit-text-size-adjust:100%;
  scroll-behavior:smooth;
  scroll-padding-top:calc(var(--header-h) + 24px);
  /* The canvas beyond the document. Every page opens on the night hero and
     closes on the ink footer, so rubber-band overscroll at either end should
     show night, not the paper that body carries for the middle of the page. */
  background:var(--ink);
}
body{
  margin:0;background:var(--paper);color:var(--on-paper);
  font-family:var(--body);font-size:var(--t-base);line-height:1.75;
  font-weight:400;-webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
img,svg{max-width:100%;display:block}
h1,h2,h3,h4{
  font-family:var(--display);font-weight:600;line-height:1.15;
  letter-spacing:-.022em;margin:0;text-wrap:balance;
}
:lang(zh-Hant-HK) h1,:lang(zh-Hant-HK) h2{letter-spacing:-.01em;line-height:1.22}
p{margin:0;text-wrap:pretty}
ul,ol{margin:0;padding:0;list-style:none}
a{color:inherit;text-decoration:none}
::selection{background:var(--lime);color:var(--ink)}

/* Focus: two rings so it survives both night and day surfaces. */
:where(a,button,input,select,textarea,summary,[tabindex]):focus-visible{
  outline:3px solid var(--focus);
  outline-offset:3px;
  border-radius:6px;
}
.night :where(a,button,input,select,textarea,[tabindex]):focus-visible{
  outline-color:var(--focus-on-ink);
}
/* White ring on the deep-green bar. */
.hdr :where(a,button,[tabindex]):focus-visible{outline-color:#FFFFFF}
a,button,label,summary{touch-action:manipulation}

.skip{
  position:fixed;top:0;left:0;transform:translateY(-110%);
  background:var(--ink);color:var(--on-ink);font-family:var(--display);
  font-weight:600;padding:14px 24px;border-radius:0 0 12px 0;z-index:1200;
  transition:transform .2s var(--ease);
}
.skip:focus,.skip:focus-visible{transform:translateY(0)}

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

/* ==========================================================================
   Layout primitives
   ========================================================================== */
.wrap{width:100%;max-width:var(--max);margin-inline:auto;padding-inline:var(--gutter)}
.band{padding-block:clamp(var(--s6),7.5vw,var(--s8))}
.band-sm{padding-block:clamp(var(--s5),6vw,var(--s6))}

.night{background:var(--ink);color:var(--on-ink)}
.night:not(.hero):not(.phero):not(.log-band){background-image:url(../img/stars.webp)}
/* Sections that sit mid-ramp declare their own start/end; see §RAMP below. */
.night p{color:var(--on-ink-2)}
.day{background:var(--paper);color:var(--on-paper)}
.day p{color:var(--on-paper-2)}

/* Section label — a mono tag, not a pill. Reads as an instrument marking. */
.tag{
  font-family:var(--mono);font-size:var(--t-xs);font-weight:500;
  letter-spacing:.11em;text-transform:uppercase;
  display:inline-flex;align-items:center;gap:10px;
  color:var(--lime-text);
}
.night .tag{color:var(--lime)}
.tag::before{
  content:"";width:22px;height:1px;background:currentColor;flex:none;
}

.sec-head{max-width:34ch;margin-bottom:clamp(var(--s4),4.5vw,var(--s5))}
.sec-head h2{font-size:var(--t-2xl);margin:var(--s2) 0 var(--s2)}
.sec-head p{font-size:var(--t-lg);color:var(--on-paper-2);max-width:52ch}
.night .sec-head p{color:var(--on-ink-2)}

/* ==========================================================================
   Buttons
   ========================================================================== */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:10px;
  min-height:52px;padding:14px 26px;border-radius:999px;border:1.5px solid transparent;
  font-family:var(--display);font-weight:600;font-size:var(--t-sm);letter-spacing:.005em;
  line-height:1.3;text-align:center;cursor:pointer;
  transition:background .2s var(--ease),border-color .2s var(--ease),
             color .2s var(--ease),transform .2s var(--ease);
  -webkit-tap-highlight-color:transparent;
}
.btn > svg{width:17px;height:17px;flex:none}
.btn-fill{background:var(--lime);color:var(--ink);border-color:var(--lime)}
.btn-fill:hover{background:var(--lime-lift);border-color:var(--lime-lift);transform:translateY(-2px)}
.btn-line{border-color:var(--line);color:var(--on-paper)}
.btn-line:hover{border-color:var(--on-paper);transform:translateY(-2px)}
.night .btn-line{border-color:var(--line-ink);color:var(--on-ink)}
.night .btn-line:hover{border-color:var(--lime);color:var(--lime)}
.btn-row{display:flex;flex-wrap:wrap;gap:var(--s2)}
@media(hover:none){.btn:hover{transform:none}}

/* ==========================================================================
   Header
   ========================================================================== */
/* The global menu is the brand green.
   Solid, not translucent: lime at 80% over a near-black hero goes olive and
   muddy, and dropping backdrop-filter also removes the containing-block trap
   that broke the mobile drawer once already.
   Everything inside flips to ink — white on lime is 1.8:1 and unusable. */
.hdr{
  position:sticky;top:0;z-index:900;
  background:var(--menu);
  border-bottom:1px solid rgba(255,255,255,.16);
  transition:box-shadow .3s var(--ease);
}
.hdr.solid{box-shadow:0 10px 30px -20px rgba(0,0,0,.75)}
.hdr .wrap{display:flex;align-items:center;gap:var(--s3);height:var(--header-h)}
.brand{display:flex;align-items:center;min-height:var(--tap);flex:none}
/* Logo scales up with the viewport — the mark carries the brand, so on a
   desktop it should read as a mark and not as a favicon. The header grows
   with it; --header-h is re-measured by JS so sticky offsets follow. */
.brand img{height:40px;width:auto;transition:height .2s var(--ease)}
@media(min-width:701px){
  .hdr .wrap{height:92px}
  .brand img{height:56px}
}
@media(min-width:1081px){
  .hdr .wrap{height:104px}
  .brand img{height:66px}
}
.nav{display:flex;align-items:center;gap:2px;margin-left:auto}
.nav a{
  display:inline-flex;align-items:center;min-height:var(--tap);padding:0 14px;
  border-radius:9px;font-size:var(--t-sm);font-weight:600;
  color:#FFFFFF;                      /* 4.8:1 on --menu */
  transition:color .2s,background .2s;
}
.nav a:hover{color:#FFFFFF;background:rgba(0,0,0,.16)}   /* darken, never lighten */
.nav a[aria-current]{color:#FFFFFF;background:rgba(0,0,0,.24)}
.hdr-act{display:flex;align-items:center;gap:var(--s1);flex:none}
/* the CTA keeps the true brand green, which now pops against the deeper bar */
.hdr-act .btn-fill{background:var(--lime);border-color:var(--lime);color:var(--ink)}
.hdr-act .btn-fill:hover{background:var(--lime-lift);border-color:var(--lime-lift)}
.lang{display:flex;border:1px solid rgba(255,255,255,.42);border-radius:999px;overflow:hidden}
.lang a{
  display:inline-flex;align-items:center;justify-content:center;
  min-width:var(--tap);min-height:var(--tap);padding:0 12px;
  font-family:var(--mono);font-size:var(--t-xs);font-weight:500;
  color:#FFFFFF;
}
.lang a[aria-current]{background:var(--lime);color:var(--ink)}   /* brand pill */
.burger{
  display:none;width:var(--tap);height:var(--tap);
  flex-direction:column;align-items:center;justify-content:center;gap:5px;
  background:transparent;border:1px solid rgba(255,255,255,.42);border-radius:11px;cursor:pointer;
}
.burger i{display:block;width:19px;height:1.6px;background:#FFFFFF;transition:.28s var(--ease)}
/* Flex + gap fixes the bar pitch at 1.6 + 5 = 6.6px, so that is exactly the
   travel that lands the outer two on the middle and makes a real X.
   (Grid auto-rows distributed extra space and produced a ">".) */
.burger[aria-expanded="true"] i:nth-child(1){transform:translateY(6.6px) rotate(45deg)}
.burger[aria-expanded="true"] i:nth-child(2){opacity:0}
.burger[aria-expanded="true"] i:nth-child(3){transform:translateY(-6.6px) rotate(-45deg)}

@media(max-width:900px){
  .burger{display:flex}
  /* NOTE: this drawer must NOT be position:fixed. The header carries a
     backdrop-filter, which makes it the containing block for fixed
     descendants — the drawer then resolves against the 76px header and
     its slide-up state lands on top of the logo. Absolute + fade avoids
     both that and showing through the translucent header bar. */
  .nav{
    position:absolute;top:100%;left:0;right:0;
    flex-direction:column;align-items:stretch;gap:0;margin:0;
    padding:var(--s2) var(--gutter) var(--s4);
    background:var(--menu);border-bottom:1px solid rgba(255,255,255,.16);
    max-height:calc(100dvh - var(--header-h));overflow-y:auto;
    opacity:0;visibility:hidden;transform:translateY(-10px);
    transition:opacity .26s var(--ease),transform .26s var(--ease),visibility .26s;
  }
  .nav.open{opacity:1;visibility:visible;transform:none}
  .nav a{min-height:52px;font-size:var(--t-lg);border-bottom:1px solid rgba(255,255,255,.14)}
  .hdr-act{margin-left:auto}      /* .nav is fixed here, so it can no longer push */
  .hdr-act .btn{display:none}
}
body.locked{overflow:hidden}
.scrim{
  position:fixed;inset:0;z-index:880;background:rgba(6,9,4,.6);
  opacity:0;visibility:hidden;transition:opacity .3s,visibility .3s;
}
body.locked .scrim{opacity:1;visibility:visible}
@media(min-width:901px){.scrim{display:none}}

/* ---- Services dropdown (nav) ----------------------------------------------
   Desktop: hover/focus panel in the green menu family (dark highlight, never
   light — same rule as the rest of the menu). Mobile: an accordion inside the
   drawer, toggled by the caret button. */
.nav-drop{position:relative;display:flex;align-items:center}
.nav-caret{
  display:inline-flex;align-items:center;justify-content:center;
  width:34px;min-height:var(--tap);padding:0;
  background:none;border:0;color:#FFFFFF;cursor:pointer;
}
.nav-caret svg{width:16px;height:16px;transition:transform .25s var(--ease)}
@media(min-width:901px){
  .nav-sub{
    position:absolute;top:100%;left:0;min-width:250px;z-index:920;
    background:#4A650F;border:1px solid rgba(255,255,255,.16);border-radius:12px;
    padding:6px;margin-top:8px;display:flex;flex-direction:column;gap:1px;
    box-shadow:0 18px 40px -22px rgba(0,0,0,.8);
    opacity:0;visibility:hidden;transform:translateY(8px);
    transition:opacity .22s var(--ease),transform .22s var(--ease),visibility .22s;
  }
  .nav-sub a{
    display:flex;align-items:center;min-height:44px;padding:10px 14px;
    border-radius:8px;color:#FFFFFF;font-size:var(--t-sm);white-space:nowrap;
  }
  .nav-sub a:hover{background:rgba(0,0,0,.22);color:#FFFFFF}
  .nav-sub a[aria-current]{background:rgba(0,0,0,.30);color:#FFFFFF}
  .nav-drop:hover .nav-sub,.nav-drop:focus-within .nav-sub,.nav-sub.open{
    opacity:1;visibility:visible;transform:none;
  }
  .nav-drop:hover .nav-caret svg,.nav-drop:focus-within .nav-caret svg,
  .nav-caret[aria-expanded="true"] svg{transform:rotate(180deg)}
}
@media(max-width:900px){
  .nav-drop{flex-wrap:wrap;align-items:stretch}
  .nav-drop-t{flex:1}
  .nav-caret{border-bottom:1px solid rgba(255,255,255,.14)}
  .nav-sub{
    flex-basis:100%;display:flex;flex-direction:column;
    overflow:hidden;max-height:0;transition:max-height .3s var(--ease);
  }
  .nav-sub.open{max-height:70vh}
  .nav-sub a{
    display:flex;align-items:center;min-height:48px;
    padding-left:calc(var(--gutter) + 6px);font-size:var(--t-base);
    color:rgba(255,255,255,.92);border-bottom:1px solid rgba(255,255,255,.10);
  }
  .nav-caret[aria-expanded="true"] svg{transform:rotate(180deg)}
}

/* ==========================================================================
   HERO — night
   ========================================================================== */
.hero{
  /* Every hero colour goes through a --h-* token, so scrubbing the dial into
     office hours can flip the whole section to day by swapping six values. */
  --h-bg:var(--ink);
  --h-fg:var(--on-ink);
  --h-fg2:var(--on-ink-2);
  --h-fg3:var(--on-ink-3);
  --h-accent:var(--lime);
  --h-line:var(--line-ink);
  --h-glow:rgba(164,210,51,.16);

  position:relative;overflow:hidden;
  background:var(--h-bg);color:var(--h-fg);
  padding-block:clamp(var(--s4),4.5vw,var(--s6)) clamp(var(--s5),6vw,var(--s7));
  transition:background-color .55s var(--ease),color .55s var(--ease);
}
/* Night hero opens the ramp. When the dial is scrubbed into day the flat
   --h-bg takes over instead (higher specificity below). */
.hero.night:not(.is-day){
  background-image:url(../img/stars.webp),linear-gradient(to bottom,var(--night-0),var(--night-2));
  background-image:url(../img/stars.webp),linear-gradient(to bottom in oklab,var(--night-0),var(--night-2));
}
/* In day state the hero is light but the band under it is still night, so
   fade the last stretch of its bottom padding back down. Sits behind the
   content (.hero .wrap is z-index 1) and inside the padding, never under text. */
.hero::after{
  content:"";position:absolute;left:0;right:0;bottom:0;z-index:0;pointer-events:none;
  height:clamp(48px,5vw,84px);opacity:0;transition:opacity .55s var(--ease);
  background:linear-gradient(to bottom in oklab,transparent,var(--night-2));
}
.hero.is-day::after{opacity:1}
/* A single soft dawn on the horizon, nothing more. */
.hero::before{
  content:"";position:absolute;inset:auto -10% -40% 30%;height:70%;
  background:radial-gradient(60% 60% at 50% 100%,var(--h-glow),transparent 70%);
  pointer-events:none;transition:background .55s var(--ease);
}

/* ---- Day state: the pointer is inside 09:30-19:00 --------------------- */
.hero.is-day{
  --h-bg:#F7F8F1;
  --h-fg:var(--on-paper);
  --h-fg2:var(--on-paper-2);
  --h-fg3:var(--on-paper-3);
  --h-accent:var(--lime-text);
  --h-line:var(--line);
  --h-glow:rgba(255,214,102,.22);      /* sunlight, not brand green */
}
.hero p{color:var(--h-fg2);transition:color .55s var(--ease)}
.hero .tag{color:var(--h-accent);transition:color .55s var(--ease)}
.hero .btn-line{border-color:var(--h-line);color:var(--h-fg)}
.hero .btn-line:hover{border-color:var(--h-accent);color:var(--h-accent)}
.hero :where(a,button,[tabindex]):focus-visible{outline-color:var(--focus-on-ink)}
.hero.is-day :where(a,button,[tabindex]):focus-visible{outline-color:var(--focus)}
.hero .wrap{position:relative;z-index:1}
.hero-grid{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,.82fr);
  gap:clamp(var(--s4),5vw,var(--s6));align-items:center;
}
.hero h1{
  font-size:var(--t-4xl);font-weight:600;margin:var(--s3) 0 var(--s3);
  max-width:15ch;
}
.hero h1 em{font-style:normal;color:var(--h-accent);transition:color .55s var(--ease)}
.hero-lead{font-size:var(--t-lg);max-width:46ch;color:var(--h-fg2)}
.hero .btn-row{margin-top:var(--s4)}

/* Facts under the hero — mono, hairline-separated, no cards. */
.facts{
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:var(--s3) clamp(var(--s3),3vw,var(--s4));
  margin-top:var(--s4);padding-top:var(--s3);border-top:1px solid var(--h-line);
  transition:border-color .55s var(--ease);
}
.facts b{
  display:block;font-family:var(--mono);font-size:var(--t-lg);font-weight:500;
  color:var(--h-accent);letter-spacing:-.01em;transition:color .55s var(--ease);
}
.facts span{font-size:var(--t-sm);color:var(--h-fg3);line-height:1.6;transition:color .55s var(--ease)}

/* ---- The dial: the one thing this page is remembered by ---------------- */
.dial-holder{position:relative;justify-self:end;width:100%;max-width:460px}
/* The dial is the control, so the wrapper is what takes focus. */
.dial-wrap{
  display:block;border-radius:50%;cursor:grab;
  /* pan-y, not none: the dial is big on a phone, so a vertical swipe over it
     must still scroll the page. Rotational drags remain available. */
  touch-action:pan-y;
  -webkit-tap-highlight-color:transparent;
}
.dial-wrap:active{cursor:grabbing}
.dial-wrap:focus-visible{outline:3px solid var(--focus-on-ink);outline-offset:6px}
.hero.is-day .dial-wrap:focus-visible{outline-color:var(--focus)}

.dial{width:100%;height:auto;overflow:visible;display:block}
.dial *{transition:stroke .55s var(--ease),fill .55s var(--ease),opacity .55s var(--ease)}
.dial .track{fill:none;stroke:rgba(233,238,225,.13);stroke-width:22}

/* Both arcs are always drawn. The one you are pointing at is the loud one. */
.dial .human{fill:none;stroke:var(--on-ink);stroke-width:22;stroke-linecap:butt;opacity:.34}
.dial .system{
  fill:none;stroke:var(--lime);stroke-width:22;stroke-linecap:butt;
  filter:drop-shadow(0 0 14px rgba(164,210,51,.45));
}
.dial .tick{stroke:rgba(233,238,225,.30);stroke-width:1.4}
.dial .tick-major{stroke:rgba(233,238,225,.6);stroke-width:1.6}
.dial .hr{
  font-family:var(--mono);font-size:12px;font-weight:500;
  fill:var(--on-ink-3);letter-spacing:.06em;
}
.dial .big{
  font-family:var(--display);font-size:62px;font-weight:600;
  fill:var(--on-ink);letter-spacing:-.03em;font-variant-numeric:tabular-nums;
}
.dial .cap{font-family:var(--mono);font-size:12px;font-weight:500;fill:var(--lime);letter-spacing:.14em}
.dial .role{font-family:var(--body);font-size:13px;fill:var(--on-ink-2)}

/* The hand. Rotated as a whole via the SVG transform attribute
   `rotate(deg 200 200)`, which already carries its own centre — so do NOT add
   transform-origin here. Setting it applies the offset a second time and flings
   the hand off-canvas at most angles. */
.dial .hand .stem{stroke:var(--on-ink);stroke-width:1.6;opacity:.5}
.dial .hand .notch{stroke:var(--lime);stroke-width:2.4;stroke-linecap:round}
.dial .hand .pip{fill:var(--ink);stroke:var(--lime);stroke-width:3.5}
.dial-wrap:active .hand .pip{stroke-width:4.5}

/* ---- Day state ------------------------------------------------------- */
.hero.is-day .dial .track{stroke:rgba(18,24,14,.09)}
.hero.is-day .dial .human{stroke:var(--on-paper);opacity:1}
.hero.is-day .dial .system{stroke:rgba(18,24,14,.15);filter:none}
.hero.is-day .dial .tick{stroke:rgba(18,24,14,.26)}
.hero.is-day .dial .tick-major{stroke:rgba(18,24,14,.5)}
.hero.is-day .dial .hr{fill:var(--on-paper-3)}
.hero.is-day .dial .big{fill:var(--on-paper)}
.hero.is-day .dial .cap{fill:var(--on-paper-2)}
.hero.is-day .dial .role{fill:var(--on-paper-3)}
.hero.is-day .dial .hand .stem{stroke:var(--on-paper);opacity:.45}
.hero.is-day .dial .hand .notch{stroke:var(--on-paper)}
.hero.is-day .dial .hand .pip{fill:#F7F8F1;stroke:var(--on-paper)}

/* Legend sits under the dial, in the same mono voice. */
.dial-key{
  display:flex;gap:var(--s3);justify-content:center;flex-wrap:wrap;
  margin-top:var(--s2);font-family:var(--mono);font-size:var(--t-xs);
  letter-spacing:.08em;color:var(--h-fg3);
}
.dial-key .k{
  display:inline-flex;align-items:center;gap:8px;
  opacity:.45;transition:opacity .4s var(--ease),color .4s var(--ease);
}
.dial-key .k.on{opacity:1;color:var(--h-fg)}
.dial-key i{width:14px;height:5px;border-radius:2px;display:block;flex:none}

/* The cost line swaps with the state; the hint never changes. */
.dial-cost{
  margin-top:10px;text-align:center;font-size:var(--t-sm);
  color:var(--h-fg2);transition:color .55s var(--ease);
}
.dial-hint{
  margin-top:6px;text-align:center;font-family:var(--mono);
  font-size:var(--t-xs);letter-spacing:.04em;color:var(--h-fg3);
  transition:color .55s var(--ease),opacity .3s var(--ease);
}
.dial-wrap:focus-visible ~ .dial-hint,
.dial-holder:hover .dial-hint{opacity:.55}
@media(hover:none){.dial-hint{display:none}}
.dial-key .k-sys{background:var(--lime)}
.dial-key .k-you{background:rgba(233,238,225,.55)}

@media(max-width:960px){
  .hero-grid{grid-template-columns:1fr;gap:var(--s5)}
  .dial-holder{justify-self:center;max-width:360px}
  .hero h1{max-width:none}
  .facts{grid-template-columns:repeat(2,minmax(0,1fr))}
}

/* ==========================================================================
   LOG — the 23:14 moment, rendered as a record not a chat mock
   ========================================================================== */
.log-band{
  color:var(--on-ink);
  background-image:url(../img/stars.webp),linear-gradient(to bottom,var(--night-2),var(--night-3));
  background-image:url(../img/stars.webp),linear-gradient(to bottom in oklab,var(--night-2),var(--night-3));
}
.log-band p{color:var(--on-ink-2)}
.log-grid{display:grid;grid-template-columns:minmax(0,.9fr) minmax(0,1.1fr);gap:clamp(var(--s4),5vw,var(--s6));align-items:start}
.log{
  border:1px solid var(--line-ink);border-radius:var(--r-lg);
  background:var(--ink);overflow:hidden;
}
.log-hd{
  display:flex;align-items:center;gap:10px;padding:14px 18px;
  border-bottom:1px solid var(--line-ink);
  font-family:var(--mono);font-size:var(--t-xs);letter-spacing:.1em;color:var(--on-ink-3);
}
.log-hd .dot{width:7px;height:7px;border-radius:50%;background:var(--lime);flex:none}
.log-hd .ch{margin-left:auto;color:var(--on-ink-3)}
.log ol{padding:6px 0}
.log li{display:grid;grid-template-columns:auto 1fr;gap:14px;padding:13px 18px}
.log li + li{border-top:1px solid rgba(164,210,51,.09)}
.log time{
  font-family:var(--mono);font-size:var(--t-xs);color:var(--on-ink-3);
  padding-top:4px;white-space:nowrap;
}
.log .who{
  display:block;font-family:var(--mono);font-size:var(--t-xs);letter-spacing:.1em;
  text-transform:uppercase;margin-bottom:3px;
}
.log .cust .who{color:var(--on-ink-3)}
.log .sys .who{color:var(--lime)}
.log .msg{font-size:var(--t-sm);line-height:1.7;color:var(--on-ink)}
.log .sys .msg{color:var(--on-ink)}
.log-foot{
  padding:14px 18px;border-top:1px solid var(--line-ink);
  font-size:var(--t-xs);color:var(--on-ink-3);line-height:1.6;
}
@media(max-width:900px){.log-grid{grid-template-columns:1fr}}

/* ==========================================================================
   DAY — where the hours go (a real weekday, not four generic cards)
   ========================================================================== */
/* ==========================================================================
   §RAMP — the two transitions
   Heights are vw, deliberately not vh: on a phone vh changes the moment the
   URL bar collapses, which would make the gradient resize mid-scroll.
   Both are real elements with real height, so their stops always land exactly
   on the section boundary no matter how long the content above them runs.
   ========================================================================== */
.dawn{
  /* night -> day. Long and eased: the old 60px linear ramp banded badly. */
  height:clamp(230px,21vw,440px);
  /* sRGB first, then the oklab build for browsers that parse it */
  background-image:linear-gradient(to bottom,
    var(--night-3) 0%,
    color-mix(in oklab,var(--paper) 4.3%,var(--night-3)) 12.5%,
    color-mix(in oklab,var(--paper) 15.6%,var(--night-3)) 25%,
    color-mix(in oklab,var(--paper) 31.6%,var(--night-3)) 37.5%,
    color-mix(in oklab,var(--paper) 50.0%,var(--night-3)) 50%,
    color-mix(in oklab,var(--paper) 68.4%,var(--night-3)) 62.5%,
    color-mix(in oklab,var(--paper) 84.4%,var(--night-3)) 75%,
    color-mix(in oklab,var(--paper) 95.7%,var(--night-3)) 87.5%,
    var(--paper) 100%);
  background-image:linear-gradient(to bottom in oklab,
    var(--night-3) 0%,
    color-mix(in oklab,var(--paper) 4.3%,var(--night-3)) 12.5%,
    color-mix(in oklab,var(--paper) 15.6%,var(--night-3)) 25%,
    color-mix(in oklab,var(--paper) 31.6%,var(--night-3)) 37.5%,
    color-mix(in oklab,var(--paper) 50.0%,var(--night-3)) 50%,
    color-mix(in oklab,var(--paper) 68.4%,var(--night-3)) 62.5%,
    color-mix(in oklab,var(--paper) 84.4%,var(--night-3)) 75%,
    color-mix(in oklab,var(--paper) 95.7%,var(--night-3)) 87.5%,
    var(--paper) 100%);
}

.dusk{
  /* day -> night. There was no transition here at all before. */
  height:clamp(230px,21vw,440px);
  /* sRGB first, then the oklab build for browsers that parse it */
  background-image:linear-gradient(to bottom,
    var(--paper) 0%,
    color-mix(in oklab,var(--ink) 4.3%,var(--paper)) 12.5%,
    color-mix(in oklab,var(--ink) 15.6%,var(--paper)) 25%,
    color-mix(in oklab,var(--ink) 31.6%,var(--paper)) 37.5%,
    color-mix(in oklab,var(--ink) 50.0%,var(--paper)) 50%,
    color-mix(in oklab,var(--ink) 68.4%,var(--paper)) 62.5%,
    color-mix(in oklab,var(--ink) 84.4%,var(--paper)) 75%,
    color-mix(in oklab,var(--ink) 95.7%,var(--paper)) 87.5%,
    var(--ink) 100%);
  background-image:linear-gradient(to bottom in oklab,
    var(--paper) 0%,
    color-mix(in oklab,var(--ink) 4.3%,var(--paper)) 12.5%,
    color-mix(in oklab,var(--ink) 15.6%,var(--paper)) 25%,
    color-mix(in oklab,var(--ink) 31.6%,var(--paper)) 37.5%,
    color-mix(in oklab,var(--ink) 50.0%,var(--paper)) 50%,
    color-mix(in oklab,var(--ink) 68.4%,var(--paper)) 62.5%,
    color-mix(in oklab,var(--ink) 84.4%,var(--paper)) 75%,
    color-mix(in oklab,var(--ink) 95.7%,var(--paper)) 87.5%,
    var(--ink) 100%);
}

.dawn,.dusk{pointer-events:none}
@media(max-width:700px){.dawn,.dusk{height:clamp(180px,48vw,320px)}}

.hours{border-top:1px solid var(--line)}
.hours li{
  display:grid;grid-template-columns:104px 1fr auto;gap:var(--s3);align-items:baseline;
  padding:var(--s3) 0;border-bottom:1px solid var(--line-2);
}
.hours time{
  font-family:var(--mono);font-size:var(--t-lg);font-weight:500;
  color:var(--on-paper);letter-spacing:-.02em;
}
.hours h3{font-size:var(--t-lg);font-weight:600;margin-bottom:6px}
.hours p{font-size:var(--t-sm);color:var(--on-paper-3);max-width:60ch}
.hours .fix{
  font-family:var(--mono);font-size:var(--t-xs);letter-spacing:.06em;
  color:var(--lime-text);white-space:nowrap;
  border:1px solid rgba(65,89,15,.28);border-radius:999px;padding:6px 13px;
  align-self:center;
}
@media(max-width:760px){
  .hours li{grid-template-columns:1fr;gap:8px;padding:var(--s3) 0}
  .hours .fix{justify-self:start;margin-top:6px}
}

/* ==========================================================================
   SERVICES — parallel options, so no 01/02/03. Labelled by the moment
   each one covers, which is the information that actually helps you choose.
   ========================================================================== */
.svc{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1px;background:var(--line)}
.svc > a{
  background:var(--paper-2);padding:clamp(24px,2.6vw,34px);
  display:flex;flex-direction:column;gap:12px;min-height:100%;
  transition:background .25s var(--ease);
}
.svc > a:hover{background:#FBFCF7}
.svc .when{
  font-family:var(--mono);font-size:var(--t-xs);letter-spacing:.1em;
  color:var(--lime-text);
}
.svc h3{font-size:var(--t-lg);font-weight:600}
.svc p{font-size:var(--t-sm);color:var(--on-paper-3);flex:1}
.svc .go{
  display:inline-flex;align-items:center;gap:8px;min-height:var(--tap);
  font-family:var(--display);font-weight:600;font-size:var(--t-sm);color:var(--on-paper);
}
.svc .go svg{width:15px;height:15px;transition:transform .25s var(--ease)}
.svc > a:hover .go svg{transform:translateX(4px)}
.svc-ico{width:26px;height:26px;color:var(--lime-text);stroke-width:1.6}
/* Odd count leaves one card alone on the last row — make it a full-width
   feature strip instead of an orphan: mono "when" on its own top line, then
   icon + title + blurb + arrow on one row. */
.svc > a.svc-wide{grid-column:1/-1;flex-direction:row;flex-wrap:wrap;align-items:center;gap:10px 28px}
.svc > a.svc-wide .when{flex-basis:100%;order:-1}
.svc > a.svc-wide .svc-ico{width:30px;height:30px}
.svc > a.svc-wide h3{flex:0 0 auto}
.svc > a.svc-wide p{flex:1 1 300px}
.svc > a.svc-wide .go{flex:0 0 auto;margin-left:auto}
@media(max-width:900px){.svc{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:600px){
  .svc{grid-template-columns:1fr}
  .svc > a.svc-wide{flex-direction:column;align-items:flex-start}
  .svc > a.svc-wide .go{margin-left:0}
}

/* ==========================================================================
   STANCE — the honesty section. Two columns: can / cannot yet.
   ========================================================================== */
.stance{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--s4)}
.stance > div{padding:clamp(24px,3vw,36px);border-radius:var(--r-lg);border:1px solid var(--line)}
.stance .can{background:var(--paper-2)}
.stance .cant{background:transparent;border-style:dashed}
.stance h3{font-size:var(--t-lg);margin-bottom:var(--s2)}
.stance li{
  display:grid;grid-template-columns:20px 1fr;gap:12px;
  font-size:var(--t-sm);color:var(--on-paper-2);padding:9px 0;
}
.stance li + li{border-top:1px solid var(--line-2)}
.stance svg{width:18px;height:18px;margin-top:5px;flex:none}
.stance .can svg{color:var(--lime-text)}
.stance .cant svg{color:var(--on-paper-3)}
@media(max-width:760px){.stance{grid-template-columns:1fr}}

/* ==========================================================================
   MARQUEE — with a real pause control (WCAG 2.2.2)
   ========================================================================== */
.rail{position:relative;border-block:1px solid var(--line);padding-block:var(--s3)}
.rail-vp{
  overflow:hidden;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);
}
.rail-track{display:flex;gap:clamp(28px,4vw,56px);width:max-content;animation:rail 46s linear infinite}
.rail-track span{
  font-family:var(--mono);font-size:var(--t-sm);letter-spacing:.03em;
  color:var(--on-paper-3);white-space:nowrap;
}
@keyframes rail{to{transform:translateX(-50%)}}
.rail.paused .rail-track{animation-play-state:paused}
.rail-btn{
  position:absolute;right:var(--gutter);top:50%;transform:translateY(-50%);
  width:var(--tap);height:var(--tap);display:grid;place-items:center;
  background:var(--paper-2);border:1px solid var(--line);border-radius:50%;
  cursor:pointer;color:var(--on-paper);z-index:2;
}
.rail-btn svg{width:15px;height:15px}
@media(prefers-reduced-motion:reduce){.rail-track{animation:none}}

/* ==========================================================================
   FAQ
   ========================================================================== */
.faq{border-top:1px solid var(--line);max-width:none}
.faq-i{border-bottom:1px solid var(--line)}
.faq-q{
  width:100%;display:grid;grid-template-columns:1fr auto;gap:var(--s3);align-items:center;
  background:none;border:0;cursor:pointer;text-align:left;
  font-family:var(--display);font-weight:600;font-size:var(--t-lg);color:var(--on-paper);
  padding:var(--s3) 0;min-height:var(--tap);line-height:1.4;
}
.faq-q .pm{position:relative;width:18px;height:18px;flex:none}
.faq-q .pm::before,.faq-q .pm::after{
  content:"";position:absolute;inset:50% 0 auto 0;height:1.6px;background:var(--on-paper);
  transition:transform .3s var(--ease);
}
.faq-q .pm::after{transform:rotate(90deg)}
.faq-i.open .faq-q .pm::after{transform:rotate(0)}
.faq-a{overflow:hidden;max-height:0;transition:max-height .38s var(--ease)}
.faq-a p{padding-bottom:var(--s3);font-size:var(--t-sm);color:var(--on-paper-2);max-width:70ch}

/* ==========================================================================
   CLOSE — back to night
   ========================================================================== */
.close-grid{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr);gap:clamp(var(--s4),5vw,var(--s6));align-items:center}
.close-grid h2{font-size:var(--t-3xl);max-width:16ch}
.close-list li{
  display:grid;grid-template-columns:auto 1fr;gap:14px;padding:13px 0;
  font-size:var(--t-sm);color:var(--on-ink-2);border-bottom:1px solid rgba(164,210,51,.12);
}
.close-list b{font-family:var(--mono);font-weight:500;color:var(--lime);white-space:nowrap}
@media(max-width:860px){.close-grid{grid-template-columns:1fr}.close-grid h2{max-width:none}}

/* ==========================================================================
   Footer
   ========================================================================== */
.ft{background:var(--ink) url(../img/stars.webp);color:var(--on-ink);border-top:1px solid var(--line-ink);padding-block:var(--s6) var(--s3)}
.ft-grid{display:grid;grid-template-columns:1.6fr 1fr 1fr 1.1fr;gap:var(--s4)}
.ft img{height:34px;width:auto;margin-bottom:var(--s2)}
.ft h5{
  font-family:var(--mono);font-size:var(--t-xs);font-weight:500;letter-spacing:.14em;
  text-transform:uppercase;color:var(--on-ink-3);margin:0 0 var(--s1);
}
.ft li a,.ft address a{
  display:inline-flex;align-items:center;min-height:var(--tap);
  font-size:var(--t-sm);color:var(--on-ink-2);transition:color .2s;
}
.ft li a:hover,.ft address a:hover{color:var(--lime)}
.ft address{font-style:normal;font-size:var(--t-sm);color:var(--on-ink-2);line-height:1.7}
.ft-note{font-size:var(--t-sm);color:var(--on-ink-3);max-width:34ch;line-height:1.7}
.ft-btm{
  margin-top:var(--s5);padding-top:var(--s3);border-top:1px solid rgba(164,210,51,.12);
  display:flex;justify-content:space-between;gap:var(--s2);flex-wrap:wrap;
  font-family:var(--mono);font-size:var(--t-xs);color:var(--on-ink-3);letter-spacing:.04em;
}
@media(max-width:900px){.ft-grid{grid-template-columns:1fr 1fr}}
@media(max-width:560px){.ft-grid{grid-template-columns:1fr}}

/* ==========================================================================
   Mobile action bar
   ========================================================================== */
.mbar{
  display:none;position:fixed;left:0;right:0;bottom:0;z-index:940;gap:10px;
  padding:10px var(--gutter) calc(10px + env(safe-area-inset-bottom));
  background:rgba(12,18,7,.95);backdrop-filter:blur(14px);
  border-top:1px solid var(--line-ink);
  transform:translateY(115%);transition:transform .3s var(--ease);
}
.mbar.up{transform:translateY(0)}
.mbar .btn{flex:1;min-height:var(--tap);padding:12px 14px;font-size:var(--t-xs)}
.mbar .btn-line{border-color:var(--line-ink);color:var(--on-ink)}
.mbar .btn-line:hover{border-color:var(--lime);color:var(--lime)}
@media(max-width:900px){
  .mbar{display:flex}
  body{padding-bottom:78px}
}

/* ==========================================================================
   Motion — one orchestrated load, then quiet reveals
   ========================================================================== */
.rise{opacity:0;transform:translateY(18px);transition:opacity .7s var(--ease),transform .7s var(--ease)}
.rise.in{opacity:1;transform:none}
.rise[data-d="1"]{transition-delay:.06s}
.rise[data-d="2"]{transition-delay:.12s}
.rise[data-d="3"]{transition-delay:.18s}
.rise[data-d="4"]{transition-delay:.24s}

.dial .system{stroke-dasharray:var(--sys-len);stroke-dashoffset:var(--sys-len)}
.dial.run .system{transition:stroke-dashoffset 1.5s cubic-bezier(.3,.8,.3,1) .25s;stroke-dashoffset:0}
.dial .hand{opacity:0;transition:opacity .5s var(--ease) 1.4s}
.dial.run .hand{opacity:1}

@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.01ms!important;animation-iteration-count:1!important;
    transition-duration:.01ms!important;scroll-behavior:auto!important;
  }
  .rise{opacity:1;transform:none}
  .dial .system{stroke-dashoffset:0}
  .dial .hand{opacity:1}
}

/* ==========================================================================
   INNER PAGES
   Same 24-hour spine: every page opens on night, drops into day for the
   substance, and closes on night with the CTA.
   ========================================================================== */

/* ---- Page hero (night, shorter than the home hero) --------------------- */
.phero{
  position:relative;overflow:hidden;
  padding-block:clamp(var(--s4),5vw,var(--s6)) clamp(var(--s5),6vw,var(--s7));
  background-image:url(../img/stars.webp),linear-gradient(to bottom,var(--night-0),var(--night-3));
  background-image:url(../img/stars.webp),linear-gradient(to bottom in oklab,var(--night-0),var(--night-3));
}
.phero::before{
  content:"";position:absolute;inset:auto -10% -50% 40%;height:80%;
  background:radial-gradient(60% 60% at 50% 100%,rgba(164,210,51,.14),transparent 70%);
  pointer-events:none;
}
.phero .wrap{position:relative;z-index:1}
.phero h1{font-size:var(--t-3xl);max-width:17ch;margin:var(--s3) 0 var(--s3)}
.phero h1 em{font-style:normal;color:var(--lime)}
.phero .lede{font-size:var(--t-lg);color:var(--on-ink-2);max-width:56ch}
.phero .btn-row{margin-top:var(--s4)}

.crumb{font-family:var(--mono);font-size:var(--t-xs);color:var(--on-ink-3);letter-spacing:.06em}
.crumb ol{display:flex;flex-wrap:wrap;align-items:center;gap:8px}
.crumb a,.crumb [aria-current]{display:inline-flex;align-items:center;min-height:var(--tap)}
.crumb a{color:var(--on-ink-3)}
.crumb a:hover{color:var(--lime)}
.crumb li:not(:last-child)::after{content:"/";margin-left:8px;opacity:.45}
.crumb [aria-current]{color:var(--on-ink-2)}

/* ---- Two-column panel pair (fit / deliverables) ------------------------ */
.pair{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--s4);align-items:start}
@media(max-width:820px){.pair{grid-template-columns:1fr}}
.pane{padding:clamp(24px,3vw,36px);border-radius:var(--r-lg);border:1px solid var(--line);background:var(--paper-2)}
.pane.quiet{background:transparent;border-style:dashed}
.pane h2,.pane h3{font-size:var(--t-lg);margin-bottom:var(--s2)}
.ticks li{display:grid;grid-template-columns:20px 1fr;gap:12px;font-size:var(--t-sm);color:var(--on-paper-2);padding:10px 0}
.ticks li + li{border-top:1px solid var(--line-2)}
.ticks svg{width:18px;height:18px;margin-top:5px;flex:none;color:var(--lime-text)}
.scope{
  margin-top:var(--s3);padding-left:14px;border-left:2px solid var(--lime);
  font-size:var(--t-sm);color:var(--on-paper-3);
}

/* ---- "What it does" — hairline grid, same family as the service grid --- */
.does{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1px;background:var(--line)}
.does > div{background:var(--paper-2);padding:clamp(22px,2.4vw,30px)}
.does h3{font-size:var(--t-lg);margin-bottom:10px}
.does p{font-size:var(--t-sm);color:var(--on-paper-3)}
@media(max-width:900px){.does{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:620px){.does{grid-template-columns:1fr}}

/* ---- Delivery steps ----------------------------------------------------
   Numbering IS used here: these really are ordered stages, so the number
   carries information the reader needs. (The service cards are parallel
   options and deliberately carry no numbers.) */
.steps{counter-reset:step;border-top:1px solid var(--line)}
.steps li{
  display:grid;grid-template-columns:76px 1fr;gap:var(--s3);
  padding:var(--s3) 0;border-bottom:1px solid var(--line-2);
}
.steps li::before{
  counter-increment:step;content:counter(step,decimal-leading-zero);
  font-family:var(--mono);font-size:var(--t-xl);font-weight:500;
  color:var(--lime-text);line-height:1;
}
.steps h3{font-size:var(--t-lg);margin-bottom:6px}
.steps p{font-size:var(--t-sm);color:var(--on-paper-3);max-width:66ch}
@media(max-width:620px){
  .steps li{grid-template-columns:1fr;gap:8px}
  .steps li::before{font-size:var(--t-lg)}
}

/* ---- Capability table (about) ------------------------------------------ */
.tbl-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch}
.tbl{width:100%;border-collapse:collapse;min-width:640px;text-align:left}
.tbl th,.tbl td{padding:16px 18px;border-bottom:1px solid var(--line-2);vertical-align:top}
.tbl thead th{
  font-family:var(--mono);font-size:var(--t-xs);font-weight:500;letter-spacing:.11em;
  text-transform:uppercase;color:var(--on-paper-3);border-bottom:1px solid var(--line);
}
.tbl tbody th{font-family:var(--display);font-weight:600;font-size:var(--t-sm);color:var(--on-paper);width:24%}
.tbl td{font-size:var(--t-sm);color:var(--on-paper-2)}
.lvl{display:inline-flex;align-items:center;gap:7px;white-space:nowrap;font-family:var(--mono);font-size:var(--t-xs);color:var(--on-paper-2)}
.lvl i{display:flex;gap:3px}
.lvl b{width:7px;height:7px;border-radius:50%;background:var(--line);display:block}
.lvl b.on{background:var(--lime-text)}
.tbl-hint{font-size:var(--t-xs);color:var(--on-paper-3);margin-top:10px;font-family:var(--mono)}
@media(min-width:760px){.tbl-hint.only-sm{display:none}}

/* ---- Promise cards ----------------------------------------------------- */
.promise{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:1px;background:var(--line)}
.promise > div{background:var(--paper-2);padding:clamp(22px,2.6vw,32px)}
.promise .n{font-family:var(--mono);font-size:var(--t-xs);letter-spacing:.11em;color:var(--lime-text)}
.promise h3{font-size:var(--t-lg);margin:8px 0 8px}
.promise p{font-size:var(--t-sm);color:var(--on-paper-3)}
@media(max-width:700px){.promise{grid-template-columns:1fr}}

/* ---- "Which one do I need" match table --------------------------------- */
.match{border-top:1px solid var(--line)}
.match li{
  display:grid;grid-template-columns:1fr auto;gap:var(--s3);align-items:center;
  padding:var(--s3) 0;border-bottom:1px solid var(--line-2);
}
.match q{font-size:var(--t-base);color:var(--on-paper);quotes:"「" "」"}
.match a{
  font-family:var(--mono);font-size:var(--t-xs);letter-spacing:.05em;color:var(--lime-text);
  border:1px solid rgba(65,89,15,.30);border-radius:999px;padding:0 15px;white-space:nowrap;
  display:inline-flex;align-items:center;min-height:var(--tap);
}
.match a:hover{background:rgba(65,89,15,.07);color:var(--lime-text)}
@media(max-width:720px){
  .match li{grid-template-columns:1fr;gap:10px;align-items:start}
  .match a{justify-self:start}
}

/* ---- Numbered plain list (what the quote spells out) ------------------- */
.spell{counter-reset:s}
.spell li{
  display:grid;grid-template-columns:28px 1fr;gap:12px;
  font-size:var(--t-sm);color:var(--on-paper-2);padding:11px 0;
}
.spell li + li{border-top:1px solid var(--line-2)}
.spell li::before{
  counter-increment:s;content:counter(s);font-family:var(--mono);
  font-size:var(--t-xs);color:var(--lime-text);padding-top:3px;
}

/* ---- Contact form ------------------------------------------------------ */
.form-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--s3)}
.field{display:flex;flex-direction:column;gap:7px}
.field.wide{grid-column:1/-1}
.field label{font-family:var(--display);font-weight:600;font-size:var(--t-sm);color:var(--on-paper)}
.req{color:var(--danger);margin-left:3px}
.field input,.field select,.field textarea{
  font-family:var(--body);font-size:16px;line-height:1.6;color:var(--on-paper);
  background:var(--paper-2);border:1px solid rgba(18,24,14,.24);border-radius:var(--r);
  padding:13px 15px;width:100%;min-height:var(--tap);
  transition:border-color .2s var(--ease),box-shadow .2s var(--ease);
}
.field textarea{min-height:140px;resize:vertical}
.field select{
  appearance:none;padding-right:44px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2341590F' stroke-width='2.4'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 15px center;background-size:17px;
}
.field ::placeholder{color:var(--on-paper-3)}
.hint{font-size:var(--t-xs);color:var(--on-paper-3);line-height:1.6}
.field-error{display:none;font-size:var(--t-xs);font-weight:700;color:var(--danger);line-height:1.5}
.field.bad .field-error{display:block}
.field.bad input,.field.bad select,.field.bad textarea{border-color:var(--danger);background:var(--danger-bg)}
.form-alert{
  display:none;margin-bottom:var(--s3);padding:16px 18px;border-radius:var(--r);
  background:var(--danger-bg);border:1px solid rgba(163,34,23,.34);color:#7A1911;
}
.form-alert.show{display:block}
.form-alert h2{font-size:var(--t-base);margin-bottom:8px;color:#7A1911}
.form-alert ol{padding-left:18px;list-style:decimal;display:flex;flex-direction:column;gap:5px}
.form-alert a{color:#7A1911;text-decoration:underline;font-weight:700;font-size:var(--t-sm)}
.btn[aria-busy="true"]{opacity:.7;pointer-events:none}
@media(max-width:640px){.form-grid{grid-template-columns:1fr}}

/* ---- Contact tiles ----------------------------------------------------- */
.tiles{display:flex;flex-direction:column;gap:1px;background:var(--line);border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden}
.tiles > div{background:var(--paper-2);padding:20px 22px;display:grid;grid-template-columns:22px 1fr;gap:14px}
.tiles svg{width:20px;height:20px;color:var(--lime-text);margin-top:4px}
.tiles b{display:block;font-family:var(--display);font-size:var(--t-sm);margin-bottom:2px}
.tiles a,.tiles p{font-size:var(--t-sm);color:var(--on-paper-2)}
.tiles a{display:inline-flex;align-items:center;min-height:var(--tap);text-decoration:underline;text-underline-offset:3px}
.tiles a:hover{color:var(--lime-text)}
.tiles address{font-style:normal;font-size:var(--t-sm);color:var(--on-paper-2);line-height:1.7}

/* ---- Centred single-message pages (thank-you / 404) -------------------- */
.solo{min-height:64vh;display:grid;place-items:center;text-align:center}
.solo .wrap{max-width:660px}
.solo h1{font-size:var(--t-3xl);margin:var(--s3) 0 var(--s3)}
.solo p{font-size:var(--t-lg);color:var(--on-ink-2)}
.solo .btn-row{justify-content:center;margin-top:var(--s4)}
.solo .next{margin-top:var(--s5);padding-top:var(--s3);border-top:1px solid var(--line-ink);text-align:left}
.solo .next li{border-bottom:1px solid rgba(164,210,51,.10)}
.solo .next a{display:flex;align-items:center;justify-content:space-between;gap:var(--s2);
  min-height:56px;font-size:var(--t-sm);color:var(--on-ink-2)}
.solo .next a:hover{color:var(--lime)}
.solo .next svg{width:15px;height:15px;flex:none}

/* ---- Related services (night strip) ------------------------------------ */
.rel{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1px;background:var(--line-ink)}
.rel > a{background:var(--card);padding:24px 22px;display:flex;flex-direction:column;gap:9px;transition:background .25s var(--ease)}
.rel > a:hover{background:#20301A}
.rel h3{font-size:var(--t-base);color:var(--on-ink)}
.rel p{font-size:var(--t-sm);color:var(--on-ink-2);flex:1}  /* --on-ink-3 was 4.33:1 on --card */
.rel span{font-family:var(--mono);font-size:var(--t-xs);color:var(--lime);letter-spacing:.05em;
  display:inline-flex;align-items:center;gap:6px;min-height:var(--tap)}
.rel span svg{width:15px;height:15px;flex:none;transition:transform .25s var(--ease)}
.rel > a:hover span svg{transform:translateX(4px)}
.rel-ico{width:24px;height:24px;color:var(--lime);stroke-width:1.6}
@media(max-width:860px){.rel{grid-template-columns:1fr}}

/* Consecutive day bands stacked their full padding twice, leaving a dead
   half-screen between sections. Halve the join. */
.day + .day.band,
.day + .day.band-sm{padding-top:clamp(var(--s4),4.5vw,var(--s6))}
.night + .night.band,
.night + .night.band-sm{padding-top:clamp(var(--s4),4.5vw,var(--s6))}

/* ==========================================================================
   Pointer glow
   One faint light following the cursor. `screen` blending means it reads on
   the night sections and does essentially nothing on paper, so a single layer
   serves the whole page. Moved by transform only — no repaint per frame.
   ========================================================================== */
.glow{
  position:fixed;top:0;left:0;z-index:0;pointer-events:none;
  width:820px;height:820px;margin:-410px 0 0 -410px;
  background:radial-gradient(closest-side,rgba(164,210,51,.055),rgba(164,210,51,0) 70%);
  mix-blend-mode:screen;
  opacity:0;transition:opacity .45s var(--ease);
  will-change:transform;
}
.glow.on{opacity:1}
/* Content sits above the glow everywhere. .hero/.phero already declare this;
   the base rule makes it true for every other section too. */
.wrap{position:relative;z-index:1}
@media(prefers-reduced-motion:reduce){.glow{display:none}}

/* ==========================================================================
   23:14 — the phone on the bedside table
   The point of this block is that nobody is awake. So the scene states it:
   you are asleep, the system is online, and the phone lights up on its own.
   ========================================================================== */
.phone-wrap{display:flex;flex-direction:column;align-items:center;gap:var(--s2)}

.sleep-row{
  display:flex;gap:var(--s3);flex-wrap:wrap;justify-content:center;align-self:stretch;
  font-family:var(--mono);font-size:var(--t-xs);letter-spacing:.08em;
}
.sleep-row span{display:inline-flex;align-items:center;gap:8px}
.s-you{color:var(--on-ink-3)}
.s-sys{color:var(--lime)}
.moon{width:15px;height:15px;flex:none}
.pulse{
  width:7px;height:7px;border-radius:50%;background:var(--lime);flex:none;
  box-shadow:0 0 0 0 rgba(164,210,51,.55);animation:pulse 2.6s ease-out infinite;
}
@keyframes pulse{70%,100%{box-shadow:0 0 0 9px rgba(164,210,51,0)}}

/* ---- the handset ------------------------------------------------------- */
.phone{
  position:relative;width:100%;max-width:376px;
  padding:14px 12px;border-radius:34px;
  background:linear-gradient(160deg,var(--card),var(--night-2));
  box-shadow:0 0 0 1px rgba(233,238,225,.10),
             0 34px 60px -30px rgba(0,0,0,.85);
  transition:box-shadow .9s var(--ease);
}
/* Asleep: the screen is dark and the handset casts no light. */
.phone.lit{box-shadow:0 0 0 1px rgba(164,210,51,.30),
                     0 34px 70px -26px rgba(0,0,0,.85),
                     0 0 60px -12px rgba(164,210,51,.28)}
.phone-slit{
  position:absolute;top:7px;left:50%;transform:translateX(-50%);
  width:46px;height:4px;border-radius:3px;background:rgba(233,238,225,.16);
}
.phone-screen{
  position:relative;border-radius:24px;overflow:hidden;background:var(--ink);
  filter:brightness(.42) saturate(.6);
  transition:filter 1.1s var(--ease);
}
.phone.lit .phone-screen{filter:none}

/* ---- the notification that wakes it ------------------------------------ */
.notif{
  display:grid;gap:2px;margin:10px 10px 0;padding:11px 14px;border-radius:14px;
  background:rgba(164,210,51,.14);border:1px solid rgba(164,210,51,.34);
  opacity:0;transform:translateY(-14px);
  transition:opacity .5s var(--ease),transform .5s var(--ease);
}
.notif.in{opacity:1;transform:none}
.notif-app{font-family:var(--mono);font-size:var(--t-xs);letter-spacing:.14em;color:var(--lime)}
.notif-txt{font-size:var(--t-sm);color:var(--on-ink)}

/* ---- messages arrive one at a time -------------------------------------
   Deliberately slow: the whole point is that this happened while you slept,
   not that it happened instantly. */
.phone .log{border:0;border-radius:0;background:transparent}
.phone .log li{opacity:0;transform:translateY(10px);
  transition:opacity .55s var(--ease),transform .55s var(--ease)}
.phone .log li.in{opacity:1;transform:none}
.phone .log-foot{opacity:0;transition:opacity .6s var(--ease)}
.phone .log-foot.in{opacity:1}

.replay{
  display:inline-flex;align-items:center;gap:8px;min-height:var(--tap);
  padding:0 16px;border-radius:999px;cursor:pointer;
  background:transparent;border:1px solid var(--line-ink);color:var(--on-ink-2);
  font-family:var(--mono);font-size:var(--t-xs);letter-spacing:.06em;
  transition:border-color .2s,color .2s;
}
.replay:hover{border-color:var(--lime);color:var(--lime)}
.replay svg{width:15px;height:15px}

@media(prefers-reduced-motion:reduce){
  .phone-screen{filter:none}
  .notif,.phone .log li,.phone .log-foot{opacity:1;transform:none}
  .pulse{animation:none}
}
@media(max-width:900px){.phone{max-width:340px}}


/* ==========================================================================
   Stars
   Hong Kong's night sky is never black — it is warm from the street light
   below, and only a handful of stars get through. Hence the warm ramp and a
   sparse field rather than a planetarium.

   Painted as an extra background layer on the night sections themselves, not
   as a fixed blended overlay. The overlay version was one full-viewport layer
   with 92 gradients and mix-blend-mode — fine at 900px, but it made a tall
   render collapse, and two blended full-viewport layers (this plus the pointer
   glow) is more compositing than a marketing page should ask for.
   Static: the ambient-motion budget is already spent on the dial and the rail.
   ========================================================================== */
.night,.hero,.phero,.log-band,.ft{background-repeat:repeat,no-repeat}

/* ==========================================================================
   Per-service interactive animation (under each service hero)
   One scrubbable instrument per page — pointer drag / hover / keyboard set a
   value 0–100 and the SVG scene redraws. Same interaction grammar as the dial.
   ========================================================================== */
.anim-band{padding-top:clamp(var(--s4),4.5vw,var(--s6))}
.anim-head{max-width:60ch;margin-bottom:var(--s3)}
.anim-head h2{font-size:var(--t-2xl);color:var(--on-ink);margin-top:var(--s2)}
.anim-head .tag{color:var(--lime)}
.svc-anim{
  position:relative;border:1px solid var(--line-ink);border-radius:var(--r-lg);
  background:var(--card);padding:clamp(16px,2.5vw,26px);overflow:hidden;
}
.anim-stage{position:relative;width:100%}
.anim-stage svg{display:block;width:100%;height:auto}
.anim-caption{margin-top:16px;font-family:var(--mono);font-size:var(--t-sm);
  color:var(--on-ink);min-height:1.6em;letter-spacing:.02em}
.anim-track{position:relative;height:3px;border-radius:3px;background:rgba(255,255,255,.12);margin-top:12px}
.anim-fill{position:absolute;left:0;top:0;height:100%;border-radius:3px;background:var(--lime);width:0}
.anim-hint{margin-top:10px;font-size:var(--t-xs);color:var(--on-ink-3)}

/* ==========================================================================
   Services orbit hub (full-bleed white, on the services overview page)
   Logo at the centre, the seven services on a ring. Hover/focus (desktop) or
   tap (mobile) pops a detail card. Mobile collapses the ring to a list.
   ========================================================================== */
.hub-sec{background:#FFFFFF;padding-block:clamp(48px,6vw,96px)}
.hub-sec .sec-head{margin-bottom:clamp(24px,4vw,48px)}
.hub-sec .sec-head .tag{color:var(--lime-text)}
.hub-sec .sec-head h2{color:var(--on-paper)}
.hub-sec .sec-head p{color:var(--on-paper-2)}
.hub{position:relative;width:min(94vw,720px);aspect-ratio:1/1;margin:0 auto}
@keyframes hub-drift{
  0%,100%{transform:translate(-50%,-50%)}
  33%{transform:translate(-50%,-50%) translate(5px,-6px)}
  66%{transform:translate(-50%,-50%) translate(-5px,5px)}
}
.hub-spokes{position:absolute;inset:0;width:100%;height:100%;pointer-events:none}
.hub-spokes circle{fill:none;stroke:#E6EADB;stroke-width:.4}
.hub-spokes line{stroke:#ECEFE2;stroke-width:.4}
.hub-core{
  position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  width:38%;max-width:180px;aspect-ratio:1/1;border-radius:50%;
  background:#FFFFFF;border:1px solid #E6EADB;box-shadow:0 10px 34px -20px rgba(0,0,0,.35);
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;
  padding:12px;transition:opacity .3s var(--ease)}
.hub-logo{width:72%;max-width:124px;height:auto}
.hub-hint{font-family:var(--mono);font-size:var(--t-xs);color:var(--on-paper-3);text-align:center}
.hub.card-open .hub-core{opacity:0}
.hub-node{
  position:absolute;transform:translate(-50%,-50%);z-index:2;
  display:flex;flex-direction:column;align-items:center;gap:7px;width:108px;
  background:none;border:0;padding:6px;cursor:pointer;color:var(--on-paper);
  animation:hub-drift var(--d,10s) ease-in-out var(--dl,0s) infinite}
@media(prefers-reduced-motion:reduce){.hub-node{animation:none}}
.hub-ico{
  width:56px;height:56px;padding:13px;border-radius:50%;box-sizing:border-box;
  background:#F3F5EC;border:1px solid #E6EADB;color:var(--lime-text);
  transition:transform .2s var(--ease),border-color .2s var(--ease),background .2s var(--ease),box-shadow .2s var(--ease)}
.hub-label{font-size:var(--t-xs);font-weight:600;text-align:center;line-height:1.2;color:var(--on-paper)}
.hub-lvl{font-family:var(--mono);font-size:10px;letter-spacing:.03em;padding:1px 7px;border-radius:999px;line-height:1.6;white-space:nowrap}
.hub-lvl.lvl-3{background:rgba(65,89,15,.14);color:var(--lime-text)}
.hub-lvl.lvl-2{background:rgba(150,110,20,.16);color:#7a5712}
.hub-lvl.lvl-1{background:rgba(0,0,0,.06);color:var(--on-paper-3)}
.hub-node:hover .hub-ico,.hub-node:focus-visible .hub-ico,.hub-node[aria-expanded="true"] .hub-ico{
  border-color:var(--lime);background:#FFFFFF;transform:translateY(-3px);box-shadow:0 10px 22px -12px rgba(65,89,15,.5)}
.hub-node:focus-visible{outline:none}
.hub-node:focus-visible .hub-ico{outline:2px solid var(--focus);outline-offset:3px}
.hub-card{
  position:absolute;left:50%;top:50%;transform:translate(-50%,-50%) scale(.92);z-index:6;
  width:min(80%,300px);background:#FFFFFF;border:1px solid #E6EADB;border-radius:16px;
  padding:22px;box-shadow:0 26px 64px -30px rgba(0,0,0,.5);text-align:left;
  opacity:0;visibility:hidden;
  transition:opacity .18s var(--ease),transform .18s var(--ease),visibility .18s}
.hub-card.show{opacity:1;visibility:visible;transform:translate(-50%,-50%) scale(1)}
.hub-card-ic{display:inline-flex;width:46px;height:46px;padding:11px;border-radius:12px;
  box-sizing:border-box;background:#F3F5EC;color:var(--lime-text);margin-bottom:12px}
.hub-card-ic svg{width:100%;height:100%}
.hub-card-when{font-family:var(--mono);font-size:var(--t-xs);color:var(--lime-text);letter-spacing:.05em;margin-bottom:6px}
.hub-card-name{font-size:var(--t-lg);color:var(--on-paper);margin-bottom:8px}
.hub-card-blurb{font-size:var(--t-sm);color:var(--on-paper-2);margin-bottom:16px;line-height:1.55}
.hub-card-go{display:inline-flex;align-items:center;gap:6px;min-height:var(--tap);
  font-family:var(--display);font-weight:600;font-size:var(--t-sm);color:var(--lime-text)}
.hub-card-go svg{width:15px;height:15px;transition:transform .2s var(--ease)}
.hub-card-go:hover svg{transform:translateX(4px)}
@media(max-width:720px){
  .hub{width:100%;aspect-ratio:auto;display:flex;flex-direction:column;gap:10px}
  .hub-spokes,.hub-core{display:none}
  .hub-node{position:static;transform:none;animation:none;flex-direction:row;width:100%;gap:14px;
    justify-content:flex-start;padding:14px 16px;border:1px solid var(--line);
    border-radius:12px;background:var(--paper-2)}
  .hub-node .hub-ico{width:46px;height:46px;padding:11px;transform:none}
  .hub-node[aria-expanded="true"] .hub-ico{transform:none}
  .hub-label{font-size:var(--t-base)}
  .hub-card{position:static;transform:none;width:100%;margin-top:2px;
    opacity:1;visibility:visible;box-shadow:none}
  .hub-card:not(.show){display:none}
}

/* ==========================================================================
   AI customer-service solution page (sales-kit content)
   ========================================================================== */
.price-hook{margin-top:var(--s3);font-family:var(--display);font-weight:600;
  font-size:var(--t-lg);color:var(--lime)}
.price-note{margin-top:6px;font-size:var(--t-sm);color:var(--on-ink-3);max-width:54ch}
.plans{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--s3)}
.plan{position:relative;background:var(--paper-2);border:1px solid var(--line);
  border-radius:var(--r-lg);padding:clamp(20px,2.4vw,28px);
  display:flex;flex-direction:column;gap:10px}
.plan-hot{border-color:var(--lime);box-shadow:0 14px 34px -20px rgba(65,89,15,.5)}
.plan-badge{position:absolute;top:-11px;left:clamp(20px,2.4vw,28px);
  background:var(--lime);color:var(--ink);font-family:var(--display);font-weight:600;
  font-size:var(--t-xs);padding:3px 10px;border-radius:999px}
.plan h3{font-size:var(--t-lg);color:var(--on-paper)}
.plan-sub{font-size:var(--t-sm);color:var(--on-paper-3)}
.plan-price{font-family:var(--display);font-weight:700;
  font-size:clamp(1.2rem,2.4vw,1.5rem);color:var(--lime-text)}
.plan .ticks{margin-top:2px}
.funds{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1px;background:var(--line)}
.funds > div{background:var(--paper-2);padding:clamp(20px,2.4vw,28px);
  display:flex;flex-direction:column;gap:8px}
.funds h3{font-size:var(--t-base);color:var(--on-paper)}
.funds p{font-size:var(--t-sm);color:var(--on-paper-3);flex:1}
.fund-badge{align-self:flex-start;font-family:var(--mono);font-size:var(--t-xs);
  color:var(--lime-text);border:1px solid var(--line);border-radius:6px;padding:3px 8px}
@media(max-width:860px){.plans{grid-template-columns:1fr}.funds{grid-template-columns:1fr}}
