/* Brand font, self-hosted (the shared font bucket sends no CORS header). The app's headers are
   Rethink Sans at its lightest weight (400) in navy over the gold swoosh bar — mirrored here. */
@font-face { font-family: "Rethink Sans"; font-weight: 400; font-display: swap; src: url(fonts/rethink-sans-400-normal.woff2) format("woff2"); }
@font-face { font-family: "Rethink Sans"; font-weight: 500; font-display: swap; src: url(fonts/rethink-sans-500-medium.woff2) format("woff2"); }
@font-face { font-family: "Rethink Sans"; font-weight: 600; font-display: swap; src: url(fonts/rethink-sans-600-semibold.woff2) format("woff2"); }
@font-face { font-family: "Rethink Sans"; font-weight: 700; font-display: swap; src: url(fonts/rethink-sans-700-bold.woff2) format("woff2"); }

/* Palette = the app's (shared/tokens.ts, web index.css, web Button/SectionHeader). */
:root {
   --bg: #fafafa; --surface: #ffffff; --surface-2: #f3f2f1; --line: #e7e6e4;
   --ink: #282725; --muted: #6f6c67; --heading: #1f3e70; --accent: #23598e;
   --gold: #d68421; --sand: #f5ecd1; --sand-ink: #703b23;
   --btn: #1f3e70; --btn-ink: #ffffff; --logo-ink: #23598e;
   --step: #1f3e70; --step-ink: #ffffff; /* step numbers + the lede's hover bar */
   --shot-border: #d6d4d1; --phone: #ffffff;
   --shadow: 0 1px 2px rgba(0,0,0,.08), 0 8px 24px rgba(20,30,50,.10), 0 24px 48px rgba(20,30,50,.06);
}
[data-theme="dark"] {
   /* = web/src/index.css .dark: grey-950 frame, grey-900 surface, grey-800 raised, grey-700 lines,
      blue-200 (#DFE3EA, a neutral near-white) for headings + body, grey-400 muted. */
   --bg: #101217; --surface: #181b22; --surface-2: #21262f; --line: #2c323c;
   --ink: #dfe3ea; --muted: #9ca3ae; --heading: #dfe3ea; --accent: #96b0d6;
   --sand: #37301a; --sand-ink: #ebd6a3;
   --btn: #c9d9f2; --btn-ink: #181b22; --logo-ink: #e6e6e6;
   --step: #dfe3ea; --step-ink: #181b22; /* = the text color, not the pale-blue button (user) */
   --shot-border: #2c323c; --phone: #2c323c;
   --shadow: 0 1px 2px rgba(0,0,0,.4), 0 12px 32px rgba(0,0,0,.45);
   color-scheme: dark;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body { margin: 0; background: var(--bg); color: var(--ink); font: 400 17px/1.6 "Rethink Sans", system-ui, -apple-system, "Segoe UI", sans-serif; -webkit-font-smoothing: antialiased; }
img { display: block; max-width: 100%; height: auto; }
a { color: var(--accent); text-underline-offset: 3px; }
.wrap { width: min(1240px, 100% - 40px); margin-inline: auto; }

/* Theme-paired screenshots: both <img>s are lazy, and a hidden lazy image is never fetched. */
[data-theme="dark"] .for-light, [data-theme="light"] .for-dark { display: none; }
/* Theme switch = one page-wide cross-fade (see the toggle script); a touch slower than the
   250ms default so it reads as a dissolve, and off for reduced-motion. */
::view-transition-old(root), ::view-transition-new(root) { animation-duration: .4s; }
@media (prefers-reduced-motion: reduce) { ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; } }

/* Logos: sigma + wordmark flip to near-white in dark; the gold hands stay gold. */
.lockup { display: block; height: 100%; width: auto; }
.lockup .ink { fill: var(--logo-ink); }
.lockup .gold { fill: var(--gold); }

/* Headings: the app's type — Rethink Sans font-thin (only 400+ is shipped, so it renders 400) in
   text-blue-900 / dark:text-blue-200. */
.heading { font-weight: 100; color: var(--heading); line-height: 1.12; margin: 0; }

/* === web/src/compos/SectionHeader, transcribed from source ===
   md: h2 "text-3xl 1920:text-4xl 2560:text-5xl mb-4 font-rethink-sans font-thin text-blue-900
        dark:text-blue-200 relative inline-block"; span "relative z-20";
        bar div "absolute -left-1 -right-1 rounded-full bg-[#d68421] z-10 bottom-1 h-1"
   sm: "text-xl 1920:text-2xl 2560:text-3xl mb-4 1920:mb-6", bar "bottom-1 h-[3px]"
   Tailwind defaults: 3xl 1.875rem/2.25rem, 4xl 2.25rem/2.5rem, 5xl 3rem/1, xl 1.25rem/1.75rem,
   2xl 1.5rem/2rem. Breakpoints from web/tailwind.config.ts: 1920 = 1850px, 2560 = 2490px. */
.section-header { position: relative; display: inline-block; margin: 0 0 1rem; font-weight: 100; color: var(--heading);
   font-size: 1.875rem; line-height: 2.25rem; }
.section-header > span { position: relative; z-index: 20; }
.section-header::after { content: ""; position: absolute; left: -0.25rem; right: -0.25rem; bottom: 0.25rem; height: 0.25rem;
   border-radius: 9999px; background: #d68421; z-index: 10; }
.section-header.sm { font-size: 1.25rem; line-height: 1.75rem; }
.section-header.sm::after { height: 3px; }
@media (min-width: 1850px) {
   .section-header { font-size: 2.25rem; line-height: 2.5rem; }
   .section-header.sm { font-size: 1.5rem; line-height: 2rem; margin-bottom: 1.5rem; }
}
@media (min-width: 2490px) {
   .section-header { font-size: 3rem; line-height: 1; }
   .section-header.sm { font-size: 1.875rem; line-height: 2.25rem; }
}

/* The hero headline wraps, which SectionHeader never does, so its bar is drawn per line
   (box-decoration-break) at the SAME geometry that component produces: 4px thick, rounded, 4px
   past each side, its top on the baseline (Rethink Sans descends 0.30em). */
.hl {
   background:
      radial-gradient(circle closest-side, #d68421 92%, transparent) 0 calc(100% - 0.3em + 4px) / 4px 4px no-repeat,
      radial-gradient(circle closest-side, #d68421 92%, transparent) 100% calc(100% - 0.3em + 4px) / 4px 4px no-repeat,
      linear-gradient(#d68421, #d68421) 2px calc(100% - 0.3em + 4px) / calc(100% - 4px) 4px no-repeat;
   box-decoration-break: clone; -webkit-box-decoration-break: clone; padding: 0 4px; margin: 0 -4px;
}

/* ---- nav ---- */
header.top { position: sticky; top: 0; z-index: 10; background: color-mix(in srgb, var(--bg) 88%, transparent); backdrop-filter: blur(10px); border-bottom: 1px solid transparent; transition: border-color .2s; }
header.top.scrolled { border-bottom-color: var(--line); }
header.top .wrap { display: flex; align-items: center; gap: 16px; height: 68px; }
header.top .brand, .hero .big-logo { display: block; }
header.top .brand { height: 26px; transition: opacity .25s, transform .25s; }
/* The hero carries the big logo; the nav's one-line logo fades in once that scrolls away. */
.js header.top:not(.show-brand) .brand { opacity: 0; transform: translateY(-4px); pointer-events: none; }
header.top .actions { margin-left: auto; display: flex; align-items: center; gap: 12px; }
@media (max-width: 480px) {
   header.top .brand { height: 11px; }   /* one-line logo + toggle + Contact must fit 360px */
   header.top .actions { gap: 8px; }
}
@media (max-width: 380px) {
   header.top .brand { height: 9px; }
   header.top .btn-sm { padding: 10px 12px; }
   .btn:not(.btn-sm) { white-space: normal; line-height: 1.3; text-align: center; }
}
@media (max-width: 340px) { header.top .brand { display: none; } } /* 4-inch phones: no room; the hero has the logo */
.theme-toggle { width: 42px; height: 42px; display: grid; place-items: center; border-radius: 8px; border: 1px solid var(--line); background: var(--surface); color: var(--heading); cursor: pointer; transition: border-color .15s; }
.theme-toggle:hover { border-color: var(--accent); }
.theme-toggle svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
[data-theme="dark"] .theme-toggle .sun, [data-theme="light"] .theme-toggle .moon { display: none; }

/* ---- buttons (the app's primary: navy fill; pale blue fill in dark) ---- */
.btn { white-space: nowrap; display: inline-flex; align-items: center; gap: 10px; padding: 14px 24px; border: 0; border-radius: 8px; font: 600 16px/1 "Rethink Sans", sans-serif; text-decoration: none; cursor: pointer; transition: filter .15s; }
.btn-primary { background: var(--btn); color: var(--btn-ink); box-shadow: 0 1px 2px rgba(0,0,0,.12), 0 2px 6px rgba(0,0,0,.08); }
.btn-primary:hover { filter: brightness(.93); }
.btn-sm { padding: 11px 16px; font-size: 15px; }

/* ---- hero: brand + tagline left, the product right ---- */
.hero { padding: clamp(40px, 6vw, 72px) 0 clamp(72px, 9vw, 120px); }
.hero .grid { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: clamp(36px, 5vw, 72px); align-items: center; }
.hero .big-logo { width: clamp(260px, 44vw, 634px); max-width: 100%; margin-bottom: clamp(28px, 3.4vw, 44px); }
.hero .big-logo .lockup { width: 100%; height: auto; } /* sized by width so it never overflows a phone */
.hero h1 { font-size: clamp(32px, 3.2vw, 46px); }
.hero .lede { font-size: clamp(18px, 1.6vw, 21px); color: var(--muted); max-width: 38ch; margin: 22px 0 32px; }
/* Number circles: digits sit high in their em box (descender space below, little above), so the
   ink centers ~0.55px above the circle's center even with line-height 1. Glyph baselines snap
   to whole pixels per element, so fractional nudges land differently on each circle; a sweep
   MEASURED at 8x (ink bounds vs circle bounds, all eight circles) found padding-top 2px is the
   only value that puts every digit within 0–0.5px of center, none high.
   The lede is the page's outline: the four step titles, each a link to its step. Full ink
   (not muted) so it reads in dark mode; numbers in --step: navy in light, the text color in dark (gold "wasn't hitting right"). */
.hero .lede-steps { list-style: none; padding: 0; display: grid; gap: 10px; counter-reset: step; color: var(--ink); }
.hero .lede-steps li { display: flex; align-items: center; gap: 12px; counter-increment: step; }
.hero .lede-steps li::before { content: counter(step); flex: none; display: inline-grid; place-items: center; width: 26px; height: 26px; border-radius: 50%; background: var(--step); color: var(--step-ink); font-weight: 700; font-size: 13px; line-height: 1; padding-top: 2px; }
/* Hover = a bar growing out from the left under the words (--step) — the admin nav's sliding
   underline: 2px, rounded, just under the baseline. Duration ∝ width (--w, unitless px set by
   script) so every bar grows at the same 0.7px/ms instead of the long ones racing. Whole-pixel
   offset + a permanent compositor layer, or the bar paints crisp while scaling and blurry once
   it stops. */
.hero .lede-steps a { position: relative; color: inherit; text-decoration: none; transition: color .3s ease-out; }
.hero .lede-steps a::after { content: ""; position: absolute; left: -4px; right: -4px; bottom: 2px; height: 2px; border-radius: 9999px; background: var(--step); transform: scaleX(0); transform-origin: left center; transition: transform calc(var(--w, 240) / 0.7 * 1ms) ease-out; will-change: transform; }
.hero .lede-steps a:hover, .hero .lede-steps a:focus-visible { color: var(--heading); outline: none; }
.hero .lede-steps a:hover::after, .hero .lede-steps a:focus-visible::after { transform: scaleX(1); }
/* Fill the first screen (minus the sticky header) so "How it works" starts below the fold
   instead of peeking over it; capped so tall monitors don't get a canyon of whitespace. */
.hero { box-sizing: border-box; min-height: min(calc(100svh - 68px), 1100px); display: grid; align-content: center; }
.step { scroll-margin-top: 84px; } /* anchor jumps land under the sticky header */
.hero .visual { position: relative; padding: 0 0 56px; }
.hero .visual .phone { position: absolute; right: -14px; bottom: 0; width: 27%; }
@media (max-width: 960px) {
   .hero .grid { grid-template-columns: 1fr; }
   .hero .visual .phone { right: 8px; }
}

/* Screenshots */
.shot { border-radius: 14px; overflow: hidden; border: 1px solid var(--shot-border); box-shadow: var(--shadow); background: var(--surface); }
/* Full page-card shots carry the app's own 1px border and rounded corners (alpha outside the
   curve), so no second frame — just a shadow that follows the card's shape. */
.shot.card { border: 0; border-radius: 0; background: none; box-shadow: none; overflow: visible; filter: drop-shadow(0 1px 2px rgba(0,0,0,.08)) drop-shadow(0 10px 24px rgba(20,30,50,.12)); }
[data-theme="dark"] .shot.card { filter: drop-shadow(0 1px 2px rgba(0,0,0,.5)) drop-shadow(0 12px 28px rgba(0,0,0,.45)); }
.shot.form { width: min(100%, 540px); justify-self: center; }
.phone { border-radius: 28px; padding: 4px; background: var(--phone); border: 1px solid var(--shot-border); box-shadow: var(--shadow); }
.phone img { border-radius: 23px; }

/* ---- how it works ---- */
section.how { padding: 24px 0 20px; }

.step { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: clamp(28px, 5vw, 72px); align-items: center; margin-bottom: clamp(80px, 10vw, 130px); }
.step .num { display: inline-grid; place-items: center; width: 38px; height: 38px; border-radius: 50%; background: var(--step); color: var(--step-ink); font-weight: 700; font-size: 16px; line-height: 1; padding-top: 2px; margin-bottom: 18px; }
.step h3 { font-size: clamp(26px, 2.6vw, 34px); margin-bottom: 16px; }
.step p { margin: 0; color: var(--muted); font-size: 18px; max-width: 42ch; }
/* Wide steps: the job + timesheet tables need the full width to be readable. The copy stays
   stacked (number, title, paragraph) like every other step — never title-left / text-right. */
.step.wide { grid-template-columns: 1fr; gap: 36px; }
.step.wide .copy p { max-width: 56ch; }
.phones { display: flex; justify-content: center; gap: clamp(16px, 3vw, 36px); align-items: flex-start; }
.phones .phone { width: min(290px, 46%); }
.phones .phone:nth-child(2) { margin-top: 56px; }
.platforms { display: flex; gap: 10px; margin-top: 22px; flex-wrap: wrap; }
.pill { display: inline-flex; align-items: center; gap: 8px; padding: 7px 14px; border-radius: 999px; background: var(--surface-2); border: 1px solid var(--line); font-weight: 600; font-size: 14px; color: var(--ink); }
.pill svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.8; }
@media (max-width: 860px) {
   .step { grid-template-columns: 1fr; }
}

/* ---- closing CTA ---- */
/* The block (header + form) is centered on the page, but inside it everything is left-aligned:
   the header sits on the form's left edge, over the inputs. No sub-copy — the form explains
   itself, and the status line says "email or phone" if neither is given. */
section.cta { padding: clamp(40px, 6vw, 80px) 0 clamp(72px, 9vw, 110px); }
.cta > .wrap { width: min(720px, 100% - 40px); } /* the wrap narrows to the form: block centered on the page, header + form left-aligned inside it */

/* ---- modals (native <dialog>): the Text messaging disclosures now; the contact form later ---- */
.modal { width: min(560px, 100% - 32px); max-height: min(90vh, 820px); padding: 32px clamp(22px, 4vw, 36px) 30px; border: 1px solid var(--shot-border); border-radius: 16px; background: var(--surface); color: var(--muted); box-shadow: var(--shadow); font-size: 16px; }
.modal::backdrop { background: rgb(16 18 23 / .45); backdrop-filter: blur(3px); }
.modal[open] { animation: modal-in .18s ease-out; }
@keyframes modal-in { from { opacity: 0; transform: translateY(8px) scale(.98); } }
.modal p { margin: 0 0 12px; }
.modal p:last-child { margin-bottom: 0; }
.modal strong { color: var(--ink); font-weight: 600; }
@media (prefers-reduced-motion: reduce) { .modal[open] { animation: none; } }
/* Text messaging modal: on desktop the opt-in phone is OVERLAID on the modal — it hangs off the
   right edge and past the top/bottom, so it can be near real size (readable) without making the
   modal itself big. The text column reserves the part of the phone that sits inside the box. */
.modal-grid { display: grid; gap: 24px; }
.modal-figure { margin: 0; }
.modal-figure .phone { border-radius: 26px; padding: 3px; }
.modal-figure .phone img { border-radius: 23px; }
@media (min-width: 900px) {
   #sms-dialog { --phone-w: min(360px, (100vh - 56px) * 640 / 1342); --phone-out: 90px;
      width: min(840px, 100% - 32px); overflow: visible; max-height: none;
      padding-right: calc(var(--phone-w) - var(--phone-out) + 40px); }
   #sms-dialog .modal-figure { position: absolute; right: calc(var(--phone-out) * -1); top: 50%;
      transform: translateY(-50%); width: var(--phone-w); }
}
@media (max-width: 899px) {
   .modal-figure { width: min(320px, 100%); justify-self: center; }
}
button.link { font: inherit; color: var(--muted); background: none; border: 0; padding: 0; cursor: pointer; }
button.link:hover { color: var(--ink); text-decoration: underline; }

/* === Inputs: transcribed from web/src/compos/InputText, InputField and shared/inputUtils ===
   field wrapper: relative, h-[60px] (labelled input) / rows*24+52 (textarea)
   label: text-sm, -top-1 -translate-y-0.5, transition-[padding,color,transform] 300ms;
          idle text-grey-700 / dark grey-400 -> focused text-blue-800 / dark blue-200, pl-4 font-medium
   chevron: w-2, absolute left-0 top-0.5, -rotate-90, opacity-0 -> 100 on focus, transition-all 200ms
   input: absolute top-[18px] w-full h-[41px] px-4, bg-grey-200 / dark grey-950, rounded-lg,
          text-lg text-blue-900 / dark blue-200, inset shadow (0 1px 2px .10 -> 0 2px 4px .20)
   outline (-1px offset): idle 1px #1f3e70 / #4a5260, hover 1px #2e4c8a / #6c7481,
          focus 2px #2e4c8a / #bcc2cd, error 2px #b91c1c / #fca5a5
   textarea: text-sm 1440:text-base 1920:text-lg 2560:text-xl, px-3 py-1.5 1440:px-4 py-2 1920:py-2.5
          2560:px-5 py-3, resize-none, font-bold while focused. (1440 = 1370px, 1920 = 1850px, 2560 = 2490px) */
:root {
   --in-bg: #e7e6e4; --in-ink: #1f3e70; --in-label: #6f6c67; --in-label-on: #2e4c8a; --in-chev: #6f6c67;
   --in-edge: #1f3e70; --in-edge-hover: #2e4c8a; --in-edge-focus: #2e4c8a; --in-red: #b91c1c; --in-red-ink: #bb2e1b;
}
[data-theme="dark"] {
   /* The admin well (grey-950) sits on a grey-900 card; here the form is straight on the grey-950
      page, so the well takes the raised grey-800 instead or it vanishes. */
   --in-bg: #21262f; --in-ink: #dfe3ea; --in-label: #9ca3ae; --in-label-on: #dfe3ea; --in-chev: #bcc2cd;
   --in-edge: #4a5260; --in-edge-hover: #6c7481; --in-edge-focus: #bcc2cd; --in-red: #fca5a5; --in-red-ink: #fca5a5;
}
.field { position: relative; min-width: 5rem; height: 60px; }
.field.area { height: calc(4 * 28px + 52px); } /* 4 rows at the 28px line height */
.field label { position: relative; top: -4px; transform: translateY(-2px); display: block; font-size: .875rem; line-height: 1.25rem;
   color: var(--in-label); transition: padding .3s cubic-bezier(.4,0,.2,1), color .3s cubic-bezier(.4,0,.2,1), transform .3s cubic-bezier(.4,0,.2,1); }
.field label svg { position: absolute; left: 0; top: 2px; width: 8px; opacity: 0; transform: rotate(-90deg); fill: var(--in-chev);
   transition: all .2s cubic-bezier(.4,0,.2,1); }
.field input, .field textarea { position: absolute; left: 0; top: 18px; width: 100%; margin: 0; border: 0; border-radius: .5rem;
   background: var(--in-bg); color: var(--in-ink); font-family: "Rethink Sans", sans-serif; font-weight: 400; /* tracking-wide is a no-op: tailwind.config replaces the letterSpacing scale */
   box-shadow: inset 0 1px 2px 0 rgba(0,0,0,.10); outline: 1px solid var(--in-edge); outline-offset: -1px; }
.field input { height: 41px; padding: 0 1rem; font-size: 1.125rem; line-height: 1.75rem; }
/* Same type as the single-line inputs at every width (the admin textarea steps 14→16→18px by
   breakpoint while its inputs sit at 18px; side by side in one form that read as two sizes). */
.field textarea { padding: .625rem 1rem; font-size: 1.125rem; line-height: 1.75rem; resize: none; }
.field input:hover, .field textarea:hover { outline-color: var(--in-edge-hover); }
.field :is(input, textarea):focus { outline: 2px solid var(--in-edge-focus); box-shadow: inset 0 2px 4px 0 rgba(0,0,0,.20); }
/* (The admin textarea goes bold on focus; its single-line inputs don't. One form, one weight.) */
.field:focus-within label { padding-left: 1rem; font-weight: 500; color: var(--in-label-on); }
.field:focus-within label svg { opacity: 1; fill: var(--in-label-on); }
.field.error :is(input, textarea) { outline: 2px solid var(--in-red); color: var(--in-red-ink); }
.field.error label { color: var(--in-red-ink); }
.field.error:focus-within label svg { fill: var(--in-red-ink); }

/* === Inputs: transcribed from web/src/compos/InputText, InputField and shared/inputUtils ===
   field wrapper: relative, h-[60px] (labelled input) / rows*24+52 (textarea)
   label: text-sm, -top-1 -translate-y-0.5, transition-[padding,color,transform] 300ms;
          idle text-grey-700 / dark grey-400 -> focused text-blue-800 / dark blue-200, pl-4 font-medium
   chevron: w-2, absolute left-0 top-0.5, -rotate-90, opacity-0 -> 100 on focus, transition-all 200ms
   input: absolute top-[18px] w-full h-[41px] px-4, bg-grey-200 / dark grey-950, rounded-lg,
          text-lg text-blue-900 / dark blue-200, inset shadow (0 1px 2px .10 -> 0 2px 4px .20)
   outline (-1px offset): idle 1px #1f3e70 / #4a5260, hover 1px #2e4c8a / #6c7481,
          focus 2px #2e4c8a / #bcc2cd, error 2px #b91c1c / #fca5a5
   textarea: text-sm 1440:text-base 1920:text-lg 2560:text-xl, px-3 py-1.5 1440:px-4 py-2 1920:py-2.5
          2560:px-5 py-3, resize-none, font-bold while focused. (1440 = 1370px, 1920 = 1850px, 2560 = 2490px) */
:root {
   --in-bg: #e7e6e4; --in-ink: #1f3e70; --in-label: #6f6c67; --in-label-on: #2e4c8a; --in-chev: #6f6c67;
   --in-edge: #1f3e70; --in-edge-hover: #2e4c8a; --in-edge-focus: #2e4c8a; --in-red: #b91c1c; --in-red-ink: #bb2e1b;
}
[data-theme="dark"] {
   /* The admin well (grey-950) sits on a grey-900 card; here the form is straight on the grey-950
      page, so the well takes the raised grey-800 instead or it vanishes. */
   --in-bg: #21262f; --in-ink: #dfe3ea; --in-label: #9ca3ae; --in-label-on: #dfe3ea; --in-chev: #bcc2cd;
   --in-edge: #4a5260; --in-edge-hover: #6c7481; --in-edge-focus: #bcc2cd; --in-red: #fca5a5; --in-red-ink: #fca5a5;
}
.field { position: relative; min-width: 5rem; height: 60px; }
.field.area { height: calc(4 * 28px + 52px); } /* 4 rows at the 28px line height */
.field label { position: relative; top: -4px; transform: translateY(-2px); display: block; font-size: .875rem; line-height: 1.25rem;
   color: var(--in-label); transition: padding .3s cubic-bezier(.4,0,.2,1), color .3s cubic-bezier(.4,0,.2,1), transform .3s cubic-bezier(.4,0,.2,1); }
.field label svg { position: absolute; left: 0; top: 2px; width: 8px; opacity: 0; transform: rotate(-90deg); fill: var(--in-chev);
   transition: all .2s cubic-bezier(.4,0,.2,1); }
.field input, .field textarea { position: absolute; left: 0; top: 18px; width: 100%; margin: 0; border: 0; border-radius: .5rem;
   background: var(--in-bg); color: var(--in-ink); font-family: "Rethink Sans", sans-serif; font-weight: 400; /* tracking-wide is a no-op: tailwind.config replaces the letterSpacing scale */
   box-shadow: inset 0 1px 2px 0 rgba(0,0,0,.10); outline: 1px solid var(--in-edge); outline-offset: -1px; }
.field input { height: 41px; padding: 0 1rem; font-size: 1.125rem; line-height: 1.75rem; }
/* Same type as the single-line inputs at every width (the admin textarea steps 14→16→18px by
   breakpoint while its inputs sit at 18px; side by side in one form that read as two sizes). */
.field textarea { padding: .625rem 1rem; font-size: 1.125rem; line-height: 1.75rem; resize: none; }
.field input:hover, .field textarea:hover { outline-color: var(--in-edge-hover); }
.field :is(input, textarea):focus { outline: 2px solid var(--in-edge-focus); box-shadow: inset 0 2px 4px 0 rgba(0,0,0,.20); }
/* (The admin textarea goes bold on focus; its single-line inputs don't. One form, one weight.) */
.field:focus-within label { padding-left: 1rem; font-weight: 500; color: var(--in-label-on); }
.field:focus-within label svg { opacity: 1; fill: var(--in-label-on); }
.field.error :is(input, textarea) { outline: 2px solid var(--in-red); color: var(--in-red-ink); }
.field.error label { color: var(--in-red-ink); }
.field.error:focus-within label svg { fill: var(--in-red-ink); }

/* ---- contact form: fields sit straight on the page (no card) ---- */
.contact-form { max-width: 720px; margin: 20px 0 0; display: grid; gap: 22px; }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
@media (max-width: 560px) { .field-row { grid-template-columns: 1fr; gap: 22px; } }
.contact-form .hp { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }
.form-actions { display: flex; align-items: center; justify-content: flex-end; gap: 18px; min-height: 44px; }
.form-status { margin: 0 auto 0 0; font-size: 15px; color: var(--muted); }
.form-status.bad { color: var(--in-red-ink); }
.form-status.good { color: var(--ink); }
/* Send is always there; while the form can't be sent it's disabled the way the admin app's
   Button is (opacity-50 cursor-not-allowed, no hover shift) and the reason sits in a tooltip
   on hover/focus — the admin's <div class="relative group"><Button disabled/><Tooltip/></div>. */
.btn[disabled] { opacity: .5; cursor: not-allowed; }
.btn[disabled]:hover { filter: none; }
.tip-group { position: relative; display: inline-block; }
/* = web Tooltip (blue variant, position above-right, wrap): grey-50/blue-800/blue-900 →
   dark grey-900/grey-600/blue-100, rounded-lg, shadow-lg, 14px rethink, 3% tracking, snug. */
.tooltip { position: absolute; right: 0; bottom: 100%; margin-bottom: 6px; padding: 8px 12px; border: 1px solid var(--tip-edge); border-radius: .5rem;
   background: var(--tip-bg); color: var(--tip-ink); box-shadow: 0 1px 2px rgba(0,0,0,.10), 0 2px 4px rgba(0,0,0,.08), 0 4px 8px rgba(0,0,0,.06);
   font: 400 14px/1.375 "Rethink Sans", sans-serif; letter-spacing: .03em; white-space: normal; width: max-content; min-width: 200px; max-width: 400px;
   opacity: 0; visibility: hidden; transition: opacity .2s; pointer-events: none; z-index: 50; }
.tip-group:hover .tooltip:not([hidden]), .tip-group:focus-within .tooltip:not([hidden]) { opacity: 1; visibility: visible; }
.tooltip[hidden] { display: none; }
:root { --tip-bg: #fafafa; --tip-edge: #2e4c8a; --tip-ink: #1f3e70; }
[data-theme="dark"] { --tip-bg: #181b22; --tip-edge: #4a5260; --tip-ink: #eceef3; }

/* ---- footer: who we are (name, operator, address, email) left, the site's links right.
   Same grid language as the sections above: two columns on wide screens, one column under
   960px where the links flow left under the identity block. ---- */
footer { border-top: 1px solid var(--line); padding: clamp(32px, 4vw, 48px) 0 clamp(40px, 5vw, 56px); color: var(--muted); font-size: 14px; line-height: 1.6; }
footer .wrap { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 28px clamp(32px, 5vw, 72px); align-items: start; }
footer .who p { margin: 0; }
footer .who a:not(.brand) { color: var(--muted); text-decoration: none; }
footer .who a:not(.brand):hover { color: var(--ink); text-decoration: underline; }
footer nav { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 10px 24px; padding-top: 4px; }
footer nav a, footer nav .link { color: var(--muted); text-decoration: none; font: inherit; }
footer nav a:hover, footer nav .link:hover { color: var(--ink); text-decoration: underline; }
@media (max-width: 960px) {
   footer .wrap { grid-template-columns: 1fr; gap: 24px; }
   footer nav { justify-content: flex-start; padding-top: 0; }
}

/* ---- scroll reveal (skipped without JS / with reduced motion) ---- */
.js .reveal { opacity: 0; transform: translateY(18px); transition: opacity .7s ease, transform .7s ease; }
.js .reveal.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
   html { scroll-behavior: auto; }
   .js .reveal { opacity: 1; transform: none; transition: none; }
}

/* ---- /download-app: the staff-facing app page (download-app.html) ----
   Layout is decided by ORIENTATION, not width: a 1032px-wide portrait iPad and a 1032px-wide
   laptop window need different layouts, and width can't tell them apart.
     landscape (laptops, desktops) → copy left, phones right, phones sized to fit the column
                                      AND the screen height (short laptops) ;
     portrait  (any tablet upright) → stacked, the column as wide as the phone pair ;
     narrow    (< 700px, phones)    → stacked, one phone, one 300px column. */
.download .hero { min-height: 100svh; padding-bottom: clamp(40px, 6vw, 72px); } /* no sticky nav to subtract; nothing below it either, so pad evenly */
.download .hero .grid { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
/* Text column scales with the viewport HEIGHT too, so short windows can't overflow through it. */
.download .hero h1 { font-size: min(clamp(34px, 3.6vw, 52px), 6svh); }
.download .hero .big-logo { width: min(clamp(260px, 44vw, 634px), 100%, 70svh); margin-bottom: min(clamp(28px, 3.4vw, 44px), 4svh); }
/* Store buttons: the two platforms as badge-shaped buttons (black in light, near-white in dark —
   the way the official badges flip). Disabled with the house tooltip until the apps are listed. */
.stores { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 30px; }
.store { display: inline-flex; align-items: center; gap: 11px; padding: 9px 18px 9px 13px; border: 0; border-radius: 10px; background: #111; color: #fff; font-family: inherit; text-align: left; cursor: pointer; box-shadow: 0 1px 2px rgba(0,0,0,.12), 0 2px 6px rgba(0,0,0,.08); transition: filter .15s; }
.store:hover { filter: brightness(1.15); }
.store svg { width: 28px; height: 28px; fill: currentColor; flex: none; }
.store small { display: block; font-size: 11px; line-height: 1; letter-spacing: .02em; opacity: .85; margin-bottom: 3px; }
.store b { display: block; font-size: 19px; line-height: 1.1; font-weight: 600; }
.store[disabled] { opacity: .5; cursor: not-allowed; }
.store[disabled]:hover { filter: none; }
[data-theme="dark"] .store { background: #eceef3; color: #101217; }
.stores-note { margin: 14px 0 0; color: var(--muted); font-size: 15px; } /* the tooltip's message for fingers: tablets and phones have no hover */
.tooltip.left { left: 0; right: auto; }
.tooltip.below { top: 100%; bottom: auto; margin: 6px 0 0; } /* under the store buttons */
/* Phones: a row, un-pinned from the landing hero's absolute/27% rule (`.download .hero .visual
   .phone` out-specifies it). Each is up to 300px, half the row minus the gap when two must share
   it, and no taller than ~85% of the screen (a 300px phone is 630px tall) on short laptops. */
.download .hero .visual { padding: 0; display: flex; justify-content: center; align-items: flex-start; gap: 28px; }
/* Height cap derived, not guessed: a phone is 2.1× its width tall (+8px frame), the second one
   sits 56px lower, and the hero pads 72px top + 72px bottom. For the pair to fit the viewport:
   2.1w + 8 + 56 + 144 ≤ 100svh  →  w ≤ 47.6svh − 99px. */
.download .hero .visual .phone { position: static; right: auto; bottom: auto; width: min(300px, calc(50% - 14px), calc(47svh - 100px)); }
.download .hero .visual .phone.second { margin-top: 56px; }

/* Portrait tablets and all narrow screens: stacked, centered, one shared column width. */
@media (orientation: portrait), (max-width: 960px) {
   .download .hero { align-content: start; padding-top: 10vh; }
   .download .hero .grid { grid-template-columns: 1fr; justify-items: center; }
   .download .hero .copy { width: min(100%, 628px); } /* = two 300px phones + the 28px gap */
   .download .hero .big-logo { width: 100%; }
   .download .hero .visual { margin-top: 24px; width: 100%; }
   .download .hero .visual .phone { width: 300px; max-width: calc(50% - 14px); }
}
/* Phones: one phone, and the column shrinks to it. */
@media (max-width: 699px) {
   .download .hero .copy { width: min(100%, 300px); }
   .download .hero .visual .phone { width: 300px; max-width: 100%; }
   .download .hero .visual .phone.second { display: none; }
}
@media (max-width: 480px) {
   .download .stores { flex-direction: column; }
   .download .store { width: 100%; justify-content: flex-start; }
}
