/* ==========================================================================
   Meridian: meridiantimezone.com

   The colour values in the TOKENS block are not web design choices. They are
   copied from Shared/SolarPalette.swift and Shared/AvailabilityTint.swift,
   which are the app's own fixed sRGB values. The solar bands *are* the data:
   they encode night, twilight and day, so they must not be swapped for
   semantic tokens that shift underneath them. If a value changes in the app,
   change it here in the same commit.

   Everything else in this file is ordinary web chrome and may be tuned freely.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. RESET
   -------------------------------------------------------------------------- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body,
h1, h2, h3, h4, h5, h6,
p, figure, blockquote, dl, dd, ol, ul {
  margin: 0;
}

ul[class],
ol[class] {
  list-style: none;
  padding: 0;
}

img,
picture,
svg {
  display: block;
  max-width: 100%;
}

input,
button,
select,
textarea {
  font: inherit;
  color: inherit;
}

button {
  background: none;
  border: 0;
  cursor: pointer;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* --------------------------------------------------------------------------
   2. TOKENS

   Light is the default. Dark arrives two ways: the visitor's system setting,
   and an explicit [data-theme] on the root element set by the theme toggle.
   The explicit value must win in both directions, which is why the dark rules
   are written twice rather than once inside the media query.
   -------------------------------------------------------------------------- */

:root {
  color-scheme: light dark;

  /* --- Basalt solar bands. From SolarPalette.palette(for: .light) --------- */
  --solar-day: #edeef1;
  --solar-twilight: #8a8d96;
  --solar-night: #23252b;

  /* --- Marks drawn on the bands ----------------------------------------- */
  --now-line: #c21807;          /* SolarPalette.nowLine, non-negotiable red  */
  --now-outline: rgb(255 255 255 / 0.92);  /* the 1pt halo                   */
  --now-text: #8f1105;
  --work-rail: #0f7a38;         /* SolarPalette.workRail                     */
  --strip-edge: rgb(35 37 43 / 0.3);
  --horizon-line: rgb(35 37 43 / 0.55);
  --day-rule: rgb(42 44 49 / 0.45);

  /* --- Availability tints. From AvailabilityTint, light-surface values ---- */
  --tint-night: #443fa8;        /* indigo */
  --tint-early: #0f5560;        /* teal   */
  --tint-working: #0b5a28;      /* green  */
  --tint-evening: #8a4508;      /* orange */
  --tint-dayoff: #0b5a48;       /* mint   */

  /* --- Surfaces ---------------------------------------------------------- */
  --page: #f2f3f5;              /* SolarPalette.pageBackground              */
  --surface: #ffffff;           /* SolarPalette.widgetCard                  */
  --surface-sunken: #e8e9ed;
  --surface-raised: #ffffff;
  --card-shadow: rgb(35 37 43 / 0.1);
  --hairline: rgb(35 37 43 / 0.14);
  --hairline-strong: rgb(35 37 43 / 0.28);

  /* --- Type -------------------------------------------------------------- */
  --text: #14161a;              /* SolarPalette.cardText(onDark: false)     */
  --text-secondary: #4a4d55;    /* cardSecondaryText                        */

  /* #62656D, not the app's eyebrowLabel #6A6D75, and the difference is
     deliberate. The app's value is tuned against ONE light ground, its page
     background #F2F3F5, where it clears 4.66:1. The web adds a second ground
     the app does not have, --surface-sunken #E8E9ED, and #6A6D75 lands 4.26:1
     there, which fails WCAG 1.4.3 for body text. #62656D measures 4.80:1 on
     the sunken surface, 5.25:1 on the page and 5.83:1 on a white card, so one
     value is safe on all three. Accessibility wins over token fidelity here
     because the eyebrow is chrome, not solar data. */
  --text-quiet: #62656d;
  --text-on-accent: #ffffff;

  /* --- Interactive ------------------------------------------------------- */
  --accent: #0b5a28;
  --accent-hover: #094a21;
  --focus-ring: #0f5560;

  /* --- Glass. Liquid Glass on chrome only, never the timeline body ------- */
  --glass-fill: rgb(255 255 255 / 0.72);
  --glass-edge: rgb(255 255 255 / 0.9);

  /* --- Radii. The app's values, in px because they are absolute there ---- */
  --radius-column: 12px;        /* Theme.Radius.column                      */
  --radius-card: 26px;          /* Theme.Radius.card                        */
  --radius-sheet: 24px;         /* Theme.Radius.sheet                       */
  --radius-pill: 999px;
  --radius-chip: 6px;

  /* --- 8pt spacing grid, as rem ------------------------------------------ */
  --space-1: 0.5rem;   /*  8px */
  --space-2: 1rem;     /* 16px */
  --space-3: 1.5rem;   /* 24px */
  --space-4: 2rem;     /* 32px */
  --space-5: 3rem;     /* 48px */
  --space-6: 4rem;     /* 64px */
  --space-7: 6rem;     /* 96px */
  --space-8: 8rem;     /* 128px */

  /* --- Layout ------------------------------------------------------------ */
  --container: 68rem;           /* 1088px */
  --container-narrow: 44rem;    /*  704px, the legal + prose measure */
  --container-wide: 78rem;      /* 1248px */

  /* --- Type scale. Fluid, so it never needs a breakpoint ------------------ */
  --font-sans: -apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display",
    "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas,
    "Liberation Mono", monospace;

  --size-display: clamp(2.5rem, 1.6rem + 4.2vw, 4.5rem);
  --size-h2: clamp(1.875rem, 1.4rem + 2.2vw, 2.75rem);
  --size-h3: clamp(1.3125rem, 1.15rem + 0.8vw, 1.625rem);
  --size-h4: clamp(1.0625rem, 1rem + 0.3vw, 1.1875rem);
  --size-lead: clamp(1.125rem, 1.05rem + 0.4vw, 1.375rem);
  --size-body: 1.0625rem;
  --size-small: 0.9375rem;
  --size-caption: 0.8125rem;
  --size-eyebrow: 0.75rem;

  /* --- Motion. Nothing animates longer than 500ms ------------------------ */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-spring: cubic-bezier(0.34, 1.4, 0.64, 1);
  --dur-fast: 140ms;
  --dur-base: 240ms;
  --dur-slow: 420ms;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --solar-day: #5a5e67;
    --solar-twilight: #3a3d45;
    --solar-night: #0d0e11;

    --now-line: #ff6b5e;
    --now-outline: rgb(0 0 0 / 0.85);
    --now-text: #ffaa9e;
    --work-rail: #35e06f;
    --strip-edge: rgb(235 236 240 / 0.24);
    --horizon-line: rgb(235 236 240 / 0.6);
    --day-rule: rgb(255 255 255 / 0.45);

    --tint-night: #c2c0ff;
    --tint-early: #8cdcea;
    --tint-working: #86efa8;
    --tint-evening: #ffc08a;
    --tint-dayoff: #8aecd0;

    --page: #000000;
    --surface: #16171b;
    --surface-sunken: #0d0e11;
    --surface-raised: #1d1f24;
    --card-shadow: rgb(0 0 0 / 0.5);
    --hairline: rgb(235 236 240 / 0.14);
    --hairline-strong: rgb(235 236 240 / 0.3);

    --text: #ffffff;
    --text-secondary: rgb(242 243 245 / 0.8);
    --text-quiet: #b4b8c0;
    --text-on-accent: #0d0e11;

    --accent: #35e06f;
    --accent-hover: #5aeb8a;
    --focus-ring: #8cdcea;

    --glass-fill: rgb(30 32 38 / 0.72);
    --glass-edge: rgb(235 236 240 / 0.16);
  }
}

:root[data-theme="dark"] {
  --solar-day: #5a5e67;
  --solar-twilight: #3a3d45;
  --solar-night: #0d0e11;

  --now-line: #ff6b5e;
  --now-outline: rgb(0 0 0 / 0.85);
  --now-text: #ffaa9e;
  --work-rail: #35e06f;
  --strip-edge: rgb(235 236 240 / 0.24);
  --horizon-line: rgb(235 236 240 / 0.6);
  --day-rule: rgb(255 255 255 / 0.45);

  --tint-night: #c2c0ff;
  --tint-early: #8cdcea;
  --tint-working: #86efa8;
  --tint-evening: #ffc08a;
  --tint-dayoff: #8aecd0;

  --page: #000000;
  --surface: #16171b;
  --surface-sunken: #0d0e11;
  --surface-raised: #1d1f24;
  --card-shadow: rgb(0 0 0 / 0.5);
  --hairline: rgb(235 236 240 / 0.14);
  --hairline-strong: rgb(235 236 240 / 0.3);

  --text: #ffffff;
  --text-secondary: rgb(242 243 245 / 0.8);
  --text-quiet: #b4b8c0;
  --text-on-accent: #0d0e11;

  --accent: #35e06f;
  --accent-hover: #5aeb8a;
  --focus-ring: #8cdcea;

  --glass-fill: rgb(30 32 38 / 0.72);
  --glass-edge: rgb(235 236 240 / 0.16);
}

/* --------------------------------------------------------------------------
   3. BASE TYPOGRAPHY
   -------------------------------------------------------------------------- */

body {
  background: var(--page);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: var(--size-body);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

h1, h2, h3, h4 {
  line-height: 1.1;
  letter-spacing: -0.022em;
  text-wrap: balance;
  font-weight: 640;
}

h1 {
  font-size: var(--size-display);
  letter-spacing: -0.032em;
  font-weight: 700;
}

h2 {
  font-size: var(--size-h2);
  letter-spacing: -0.026em;
}

h3 {
  font-size: var(--size-h3);
}

h4 {
  font-size: var(--size-h4);
  line-height: 1.3;
}

p {
  text-wrap: pretty;
}

a {
  color: inherit;
  text-decoration-color: var(--hairline-strong);
  text-underline-offset: 0.2em;
  text-decoration-thickness: 1px;
  transition: text-decoration-color var(--dur-fast) var(--ease-out);
}

a:hover {
  text-decoration-color: currentColor;
}

strong,
b {
  font-weight: 640;
}

code,
kbd,
samp {
  font-family: var(--font-mono);
  font-size: 0.92em;
}

/* Focus. One ring, everywhere, never removed. */
:focus-visible {
  outline: 3px solid var(--focus-ring);
  outline-offset: 3px;
  border-radius: 4px;
}

::selection {
  background: var(--work-rail);
  color: var(--text-on-accent);
}

.skip-link {
  position: absolute;
  top: 0;
  left: 50%;
  translate: -50% -120%;
  z-index: 100;
  padding: var(--space-2) var(--space-3);
  background: var(--surface-raised);
  color: var(--text);
  border: 1px solid var(--hairline-strong);
  border-radius: 0 0 var(--radius-chip) var(--radius-chip);
  text-decoration: none;
  font-weight: 600;
  transition: translate var(--dur-base) var(--ease-out);
}

.skip-link:focus {
  translate: -50% 0;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* --------------------------------------------------------------------------
   4. LAYOUT PRIMITIVES
   -------------------------------------------------------------------------- */

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--space-3);
}

.container--narrow {
  max-width: var(--container-narrow);
}

.container--wide {
  max-width: var(--container-wide);
}

.section {
  padding-block: clamp(var(--space-6), 10vw, var(--space-8));
}

.section--tight {
  padding-block: clamp(var(--space-5), 7vw, var(--space-6));
}

.section--sunken {
  background: var(--surface-sunken);
}

.section__head {
  max-width: 40rem;
  margin-bottom: var(--space-5);
}

.section__head--centred {
  margin-inline: auto;
  text-align: center;
}

.eyebrow {
  display: block;
  font-size: var(--size-eyebrow);
  font-weight: 640;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text-quiet);
  margin-bottom: var(--space-2);
}

.lead {
  font-size: var(--size-lead);
  line-height: 1.5;
  color: var(--text-secondary);
}

.prose > * + * {
  margin-top: var(--space-2);
}

/* --------------------------------------------------------------------------
   5. HEADER
   -------------------------------------------------------------------------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--glass-fill);
  border-bottom: 1px solid var(--hairline);
}

@supports (backdrop-filter: blur(1px)) {
  .site-header {
    backdrop-filter: saturate(180%) blur(20px);
    -webkit-backdrop-filter: saturate(180%) blur(20px);
  }
}

.site-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  min-height: 56px;
}

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-weight: 680;
  font-size: 1.0625rem;
  letter-spacing: -0.02em;
  text-decoration: none;
}

.wordmark__mark {
  width: 26px;
  height: 26px;
  border-radius: 7px;
  flex: none;
}

.site-nav {
  display: flex;
  align-items: center;
  gap: clamp(0.75rem, 2.5vw, 1.75rem);
}

.site-nav a {
  font-size: var(--size-small);
  color: var(--text-secondary);
  text-decoration: none;
  padding: 0.5rem 0;
}

.site-nav a:hover {
  color: var(--text);
}

/* The theme toggle. 44x44 target, symbol plus an accessible name. */
.theme-toggle {
  display: inline-grid;
  place-items: center;
  width: 44px;
  height: 44px;
  margin-inline-end: -0.5rem;
  border-radius: var(--radius-pill);
  color: var(--text-secondary);
  transition: background var(--dur-fast) var(--ease-out),
    color var(--dur-fast) var(--ease-out);
}

.theme-toggle:hover {
  background: var(--hairline);
  color: var(--text);
}

.theme-toggle svg {
  width: 19px;
  height: 19px;
}

.theme-toggle__moon {
  display: none;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-toggle__sun {
    display: none;
  }

  :root:not([data-theme="light"]) .theme-toggle__moon {
    display: block;
  }
}

:root[data-theme="dark"] .theme-toggle__sun {
  display: none;
}

:root[data-theme="dark"] .theme-toggle__moon {
  display: block;
}

:root[data-theme="light"] .theme-toggle__sun {
  display: block;
}

:root[data-theme="light"] .theme-toggle__moon {
  display: none;
}

/* --------------------------------------------------------------------------
   6. BUTTONS AND BADGES
   -------------------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: 44px;
  padding: 0.6875rem 1.375rem;
  border-radius: var(--radius-pill);
  font-size: var(--size-body);
  font-weight: 620;
  letter-spacing: -0.01em;
  text-decoration: none;
  white-space: nowrap;
  transition: background var(--dur-fast) var(--ease-out),
    color var(--dur-fast) var(--ease-out),
    scale var(--dur-fast) var(--ease-out);
}

.btn:active {
  scale: 0.975;
}

.btn--primary {
  background: var(--accent);
  color: var(--text-on-accent);
}

.btn--primary:hover {
  background: var(--accent-hover);
}

.btn--secondary {
  background: transparent;
  color: var(--text);
  box-shadow: inset 0 0 0 1.5px var(--hairline-strong);
}

.btn--secondary:hover {
  background: var(--hairline);
}

/* The App Store affordance. Not a link, because there is nothing to link to
   yet. It is a labelled status, and it says so out loud. */
.store-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
  min-height: 54px;
  padding: 0.5rem 1.125rem 0.5rem 1rem;
  border-radius: 12px;
  background: var(--surface-raised);
  box-shadow: inset 0 0 0 1.5px var(--hairline-strong);
  color: var(--text);
}

.store-badge__glyph {
  width: 26px;
  height: 26px;
  flex: none;
  fill: currentColor;
}

.store-badge__text {
  display: flex;
  flex-direction: column;
  line-height: 1.15;
  text-align: left;
}

.store-badge__kicker {
  font-size: 0.6875rem;
  font-weight: 640;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-quiet);
}

.store-badge__label {
  font-size: 1.0625rem;
  font-weight: 620;
  letter-spacing: -0.015em;
}

.pill {
  display: inline-flex;
  align-items: center;
  gap: 0.4375rem;
  padding: 0.3125rem 0.75rem 0.3125rem 0.625rem;
  border-radius: var(--radius-pill);
  background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--hairline-strong);
  font-size: var(--size-caption);
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--text-secondary);
}

.pill__dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--now-line);
  flex: none;
}

/* --------------------------------------------------------------------------
   7. THE SOLAR LANE FIGURE

   The app's own drawing, in CSS. Each lane sets four percentages on itself
   and the gradient falls out of them, so a lane is data plus one class rather
   than a bespoke gradient per column.

     --dawn-start   night gives way to twilight
     --dawn-end     twilight reaches full day
     --dusk-start   day gives way to twilight
     --dusk-end     twilight reaches full night

   0% is the top of the column, 100% the bottom, and the window is the app's
   own: 6 hours behind now, 18 ahead, so the now line sits at 25%.
   -------------------------------------------------------------------------- */

.lane-figure {
  /* The header row is GIVEN a height, not measured, which is the same choice
     Theme.Lane.headerHeight makes in the app and for the same reason: the now
     line is drawn once across all four columns, so it has to be placed from a
     number that is known before the type lays out. Measure the type instead
     and the line lands on a different minute than the band it names, silently,
     with nothing to catch it. */
  --head-height: 3.25rem;
  --column-height: clamp(15rem, 42vw, 22rem);
  --now-fraction: 0.25; /* LaneWindow.nowFraction: 6h behind, 18 ahead */

  position: relative;
  padding: var(--space-2);
  background: var(--surface);
  border-radius: var(--radius-card);
  box-shadow: 0 24px 60px -20px var(--card-shadow),
    0 2px 6px -2px var(--card-shadow);
}

.lane-figure__eyebrow {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
  padding: 0.25rem 0.375rem 0.625rem;
  font-size: 0.6875rem;
  font-weight: 640;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-quiet);
}

.lane-figure__lanes {
  position: relative;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  gap: 7px; /* Theme.Lane.columnGap */
}

.lane {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.lane__head {
  height: var(--head-height);
  padding-bottom: 0.4375rem;
  min-width: 0;
}

.lane__name {
  display: block;
  font-size: 0.75rem;
  font-weight: 620;
  letter-spacing: -0.01em;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.lane__clock {
  display: block;
  font-size: 0.9375rem;
  font-weight: 620;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--text);
  white-space: nowrap;
}

.lane__column {
  position: relative;
  height: var(--column-height);
  border-radius: var(--radius-column);
  overflow: hidden;
  box-shadow: inset 0 0 0 0.5px var(--strip-edge);
  background: linear-gradient(
    to bottom,
    var(--solar-night) 0%,
    var(--solar-night) var(--dawn-start, 12%),
    var(--solar-twilight) calc((var(--dawn-start, 12%) + var(--dawn-end, 18%)) / 2),
    var(--solar-day) var(--dawn-end, 18%),
    var(--solar-day) var(--dusk-start, 68%),
    var(--solar-twilight) calc((var(--dusk-start, 68%) + var(--dusk-end, 74%)) / 2),
    var(--solar-night) var(--dusk-end, 74%),
    var(--solar-night) 100%
  );
}

/* A fixed-offset lane has no sun, so it is hatched rather than shaded. The
   texture is the claim, and it survives Differentiate Without Colour. */
.lane__column--sunless {
  background: repeating-linear-gradient(
    135deg,
    var(--surface-sunken) 0 6px,
    var(--surface-raised) 6px 12px
  );
}

/* The working-hours rail. */
.lane__rail {
  position: absolute;
  left: 6px;
  width: 3px;
  top: var(--rail-top, 30%);
  height: var(--rail-height, 33%);
  border-radius: 2px;
  background: var(--work-rail);
}

/* ---------------------------------------------------------------------------
   The four demo lanes.

   These percentages live here rather than in a style="" attribute on the
   markup for a hard reason, not a stylistic one: the site's CSP is
   style-src 'self' with no 'unsafe-inline', and CSP blocks inline style
   ATTRIBUTES as well as <style> blocks. A lane whose gradient stops arrived
   inline would render as a flat unshaded box in production while looking
   perfect on a local file:// open. Keep every value in this file.

   Each lane carries all eight of its own numbers. The child marks inherit
   them, because custom properties inherit.

   The window is the app's own: 6 hours behind now, 18 ahead, drawn from
   03:41 San Francisco on 5 March. Sunrise, sunset and civil twilight are
   real values for each city on that date.
   --------------------------------------------------------------------------- */

.lane--sf {
  --dawn-start: 9.5%;  --dawn-end: 11.3%;
  --dusk-start: 60.1%; --dusk-end: 61.9%;
  --sunrise: 11.3%;    --sunset: 60.1%;
  --rail-top: 22.2%;   --rail-height: 33.3%;
}

.lane--mom {
  /* Window opens after civil dawn has already begun, so there is no night
     band at the top and no sunrise chip to place. */
  --dawn-start: 0%;    --dawn-end: 1.5%;
  --dusk-start: 46.6%; --dusk-end: 48.5%;
  --sunrise: 1.5%;     --sunset: 46.6%;
  --rail-top: 9.7%;    --rail-height: 33.3%;
}

.lane--anya {
  /* Window opens three minutes after civil dusk. The whole first half is
     night, which is the entire point of the lane. */
  --dawn-start: 48.3%; --dawn-end: 50.8%;
  --dusk-start: 97.4%; --dusk-end: 99.8%;
  --sunrise: 50.8%;    --sunset: 97.4%;
  --rail-top: 59.7%;   --rail-height: 33.3%;
}

.lane--tokyo {
  --dawn-start: 12.6%; --dawn-end: 14.3%;
  --dusk-start: 62.4%; --dusk-end: 64.1%;
  --sunrise: 14.3%;    --sunset: 62.4%;
  --rail-top: 26.3%;   --rail-height: 33.4%;
}

/* 30rem, not 26: four columns plus three gaps plus the card padding have to
   leave each availability line room for its symbol AND its label. Meaning is
   never carried by hue alone, so "Working hours" truncating to "Working ho..."
   is not a cosmetic problem, it is the label failing to do the job that lets
   the colour be decorative. */
.lane-figure-wrap {
  width: 100%;
  max-width: 30rem;
}


/* Under Differentiate Without Colour the rail gains texture, because meaning
   is never carried by hue alone. */
@media (prefers-contrast: more) {
  .lane__rail {
    background: repeating-linear-gradient(
      to bottom,
      var(--work-rail) 0 4px,
      transparent 4px 7px
    );
  }
}

/* Sunrise and sunset each carry a hairline. Civil twilight does not: it is a
   ramp, not an event. */
.lane__horizon {
  position: absolute;
  left: 0;
  right: 0;
  height: 1px;
  background: var(--horizon-line);
}

.lane__horizon--rise { top: var(--sunrise); }
.lane__horizon--set  { top: var(--sunset); }

.lane__chip--rise { top: var(--sunrise); }
.lane__chip--set  { top: var(--sunset); }

.lane__chip {
  position: absolute;
  left: 50%;
  translate: -50% -50%;
  padding: 0.125rem 0.3125rem;
  border-radius: 5px;
  background: var(--chip-fill);
  box-shadow: inset 0 0 0 0.5px var(--chip-border);
  color: var(--chip-text);
  font-size: 0.5625rem;
  font-weight: 620;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  letter-spacing: -0.01em;
}

:root {
  --chip-fill: rgb(255 255 255 / 0.9);
  --chip-border: rgb(35 37 43 / 0.35);
  --chip-text: #1a1c20;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --chip-fill: rgb(20 11 24 / 0.85);
    --chip-border: rgb(235 236 240 / 0.5);
    --chip-text: #f2f3f5;
  }
}

:root[data-theme="dark"] {
  --chip-fill: rgb(20 11 24 / 0.85);
  --chip-border: rgb(235 236 240 / 0.5);
  --chip-text: #f2f3f5;
}

/* The now line is drawn once across the whole card, not once per column, so
   it crosses the gaps between lanes unbroken. Split into the columns it would
   clip at every seam and become four marks instead of the one the layout is
   anchored to. */
.lane-figure__now {
  position: absolute;
  left: 0;
  right: 0;
  /* Measured from the top of the SOLAR COLUMN, not the top of the lane stack.
     The header row sits above it and must be added back, or the line floats
     over the names instead of crossing the bands. */
  top: calc(var(--head-height) + (var(--column-height) * var(--now-fraction)));
  height: 2px;
  background: var(--now-line);
  box-shadow: 0 0 0 1px var(--now-outline);
  pointer-events: none;
}

.lane-figure__now-label {
  position: absolute;
  right: 0;
  bottom: calc(100% + 3px);
  font-size: 0.625rem;
  font-weight: 660;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
  color: var(--now-text);
}

.lane__availability {
  display: flex;
  align-items: center;
  gap: 0.3125rem;
  padding-top: 0.4375rem;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: -0.005em;
  white-space: nowrap;
  overflow: hidden;
}

.lane__availability svg {
  width: 11px;
  height: 11px;
  flex: none;
  fill: currentColor;
}

.lane__availability span {
  overflow: hidden;
  text-overflow: ellipsis;
}

.is-working  { color: var(--tint-working); }
.is-night    { color: var(--tint-night); }
.is-early    { color: var(--tint-early); }
.is-evening  { color: var(--tint-evening); }
.is-dayoff   { color: var(--tint-dayoff); }
.is-nosun    { color: var(--text-quiet); }

/* --------------------------------------------------------------------------
   8. HERO
   -------------------------------------------------------------------------- */

.hero {
  padding-block: clamp(var(--space-5), 8vw, var(--space-7))
    clamp(var(--space-6), 9vw, var(--space-8));
}

.hero__grid {
  display: grid;
  gap: clamp(var(--space-5), 6vw, var(--space-6));
  align-items: center;
}

@media (min-width: 56rem) {
  .hero__grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  }
}

.hero__title {
  margin-block: var(--space-3) 0;
}

.hero__lead {
  margin-top: var(--space-3);
  max-width: 34rem;
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-4);
}

.hero__note {
  margin-top: var(--space-2);
  font-size: var(--size-caption);
  color: var(--text-quiet);
}

/* --------------------------------------------------------------------------
   9. FEATURE ROWS
   -------------------------------------------------------------------------- */

.feature {
  display: grid;
  gap: clamp(var(--space-4), 6vw, var(--space-6));
  align-items: center;
  padding-block: clamp(var(--space-5), 7vw, var(--space-7));
}

.feature + .feature {
  border-top: 1px solid var(--hairline);
}

@media (min-width: 52rem) {
  .feature {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }

  .feature--flip .feature__media {
    order: -1;
  }
}

.feature__body {
  max-width: 32rem;
}

.feature__body p {
  margin-top: var(--space-2);
  color: var(--text-secondary);
  font-size: var(--size-lead);
  line-height: 1.55;
}

.feature__media {
  display: flex;
  justify-content: center;
}

/* --------------------------------------------------------------------------
   10. DEVICE FRAMES

   The screenshots are unframed captures. The bezel is drawn here so it costs
   no pixels and follows the theme.
   -------------------------------------------------------------------------- */

.device {
  position: relative;
  background: var(--surface-raised);
  box-shadow: 0 30px 70px -24px var(--card-shadow),
    0 3px 10px -3px var(--card-shadow),
    inset 0 0 0 1px var(--hairline-strong);
}

.device img {
  width: 100%;
  height: auto;
  display: block;
}

.device--phone {
  width: min(100%, 17.5rem);
  padding: 8px;
  border-radius: 42px;
}

.device--phone img {
  border-radius: 34px;
}

.device--tablet {
  width: min(100%, 34rem);
  padding: 10px;
  border-radius: 26px;
}

.device--tablet img {
  border-radius: 17px;
}

.device--watch {
  width: min(100%, 11rem);
  padding: 7px;
  border-radius: 46px;
}

.device--watch img {
  border-radius: 40px;
}

.device-cluster {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: clamp(var(--space-2), 3vw, var(--space-4));
  flex-wrap: wrap;
}

/* --------------------------------------------------------------------------
   11. CARD GRIDS
   -------------------------------------------------------------------------- */

.grid {
  display: grid;
  gap: var(--space-3);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
}

.card {
  padding: var(--space-3);
  background: var(--surface);
  border-radius: var(--radius-sheet);
  box-shadow: inset 0 0 0 1px var(--hairline);
}

.card h3,
.card h4 {
  margin-bottom: 0.5rem;
}

.card p {
  color: var(--text-secondary);
  font-size: var(--size-small);
}

.card__icon {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  margin-bottom: var(--space-2);
  border-radius: 11px;
  background: var(--surface-sunken);
}

.card__icon svg {
  width: 20px;
  height: 20px;
  fill: currentColor;
}

/* --------------------------------------------------------------------------
   12. THE PROMISE BLOCK
   -------------------------------------------------------------------------- */

.promise {
  background: var(--surface);
  border-radius: var(--radius-card);
  padding: clamp(var(--space-4), 5vw, var(--space-6));
  box-shadow: inset 0 0 0 1px var(--hairline);
}

.promise__list {
  display: grid;
  gap: var(--space-3);
  margin-top: var(--space-4);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
}

.promise__item {
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
}

.promise__check {
  flex: none;
  width: 22px;
  height: 22px;
  margin-top: 2px;
  fill: var(--accent);
}

/* h3, not h4: these sit directly under the promise section's h2, and jumping
   a level breaks heading-outline navigation for screen reader users. */
.promise__item h3 {
  font-size: var(--size-h4);
  line-height: 1.3;
  margin-bottom: 0.25rem;
}

.promise__item p {
  font-size: var(--size-small);
  color: var(--text-secondary);
  line-height: 1.5;
}

/* --------------------------------------------------------------------------
   13. NEWSLETTER
   -------------------------------------------------------------------------- */

.signup {
  max-width: 32rem;
}

.signup--centred {
  margin-inline: auto;
  text-align: center;
}

.signup__form {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  margin-top: var(--space-3);
}

.signup__field {
  flex: 1 1 15rem;
  min-width: 0;
}

.signup__input {
  width: 100%;
  min-height: 48px;
  padding: 0.625rem 1rem;
  border-radius: var(--radius-pill);
  background: var(--surface-raised);
  border: 1.5px solid var(--hairline-strong);
  color: var(--text);
  font-size: var(--size-body);
  transition: border-color var(--dur-fast) var(--ease-out);
}

.signup__input::placeholder {
  color: var(--text-quiet);
}

.signup__input:hover {
  border-color: var(--text-quiet);
}

.signup__input:focus-visible {
  border-color: var(--focus-ring);
}

.signup__submit {
  flex: 0 0 auto;
  min-height: 48px;
}

.signup__note {
  margin-top: var(--space-2);
  font-size: var(--size-caption);
  color: var(--text-quiet);
}

.signup__note a {
  color: var(--text-secondary);
}

/* --------------------------------------------------------------------------
   14. FAQ
   -------------------------------------------------------------------------- */

.faq {
  max-width: var(--container-narrow);
  margin-inline: auto;
}

.faq__item {
  border-bottom: 1px solid var(--hairline);
}

.faq__item summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: var(--space-3) 0;
  min-height: 44px;
  font-size: var(--size-h4);
  font-weight: 620;
  letter-spacing: -0.015em;
  cursor: pointer;
  list-style: none;
}

.faq__item summary::-webkit-details-marker {
  display: none;
}

.faq__item summary::after {
  content: "";
  flex: none;
  width: 11px;
  height: 11px;
  border-right: 2px solid var(--text-quiet);
  border-bottom: 2px solid var(--text-quiet);
  rotate: 45deg;
  translate: 0 -3px;
  transition: rotate var(--dur-base) var(--ease-out);
}

.faq__item[open] summary::after {
  rotate: -135deg;
  translate: 0 3px;
}

.faq__answer {
  padding-bottom: var(--space-3);
  color: var(--text-secondary);
  max-width: 38rem;
}

.faq__answer > * + * {
  margin-top: var(--space-2);
}

/* --------------------------------------------------------------------------
   15. FOOTER
   -------------------------------------------------------------------------- */

.site-footer {
  border-top: 1px solid var(--hairline);
  padding-block: var(--space-5);
  font-size: var(--size-small);
  color: var(--text-secondary);
}

.site-footer__grid {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
}

.site-footer h2 {
  font-size: var(--size-eyebrow);
  font-weight: 640;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text-quiet);
  margin-bottom: var(--space-2);
}

.site-footer ul {
  display: grid;
  gap: 0.625rem;
}

.site-footer a {
  text-decoration: none;
}

.site-footer a:hover {
  text-decoration: underline;
}

.site-footer__legal {
  margin-top: var(--space-5);
  padding-top: var(--space-3);
  border-top: 1px solid var(--hairline);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-3);
  align-items: center;
  justify-content: space-between;
  font-size: var(--size-caption);
  color: var(--text-quiet);
}

/* --------------------------------------------------------------------------
   16. LEGAL AND PROSE PAGES
   -------------------------------------------------------------------------- */

.doc {
  max-width: var(--container-narrow);
  margin-inline: auto;
  padding-block: var(--space-6);
}

.doc__meta {
  margin-top: var(--space-2);
  font-size: var(--size-small);
  color: var(--text-quiet);
}

.doc h2 {
  font-size: var(--size-h3);
  margin-top: var(--space-5);
  margin-bottom: var(--space-2);
  scroll-margin-top: 5rem;
}

.doc h3 {
  font-size: var(--size-h4);
  margin-top: var(--space-4);
  margin-bottom: var(--space-1);
  scroll-margin-top: 5rem;
}

.doc p,
.doc ul,
.doc ol,
.doc table {
  margin-top: var(--space-2);
}

.doc ul,
.doc ol {
  padding-left: 1.25rem;
}

.doc li + li {
  margin-top: 0.5rem;
}

.doc table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--size-small);
  display: block;
  overflow-x: auto;
}

.doc th,
.doc td {
  text-align: left;
  padding: 0.625rem 0.75rem;
  border-bottom: 1px solid var(--hairline);
  vertical-align: top;
}

.doc th {
  font-weight: 640;
  color: var(--text);
  white-space: nowrap;
}

.doc td {
  color: var(--text-secondary);
}

.doc__toc {
  margin-top: var(--space-4);
  padding: var(--space-3);
  background: var(--surface);
  border-radius: var(--radius-sheet);
  box-shadow: inset 0 0 0 1px var(--hairline);
}

.doc__toc h2 {
  margin-top: 0;
  font-size: var(--size-eyebrow);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--text-quiet);
}

.doc__toc ol {
  margin-top: var(--space-2);
  columns: 2;
  column-gap: var(--space-3);
  font-size: var(--size-small);
}

@media (max-width: 34rem) {
  .doc__toc ol {
    columns: 1;
  }
}

.doc__callout {
  margin-top: var(--space-3);
  padding: var(--space-3);
  border-radius: var(--radius-sheet);
  background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--hairline);
}

.doc__callout p:first-child {
  margin-top: 0;
}

/* --------------------------------------------------------------------------
   16b. SMALL NAMED PIECES

   Every one of these exists because the CSP forbids inline style attributes,
   so a one-off `style="margin-top: 2rem"` is not available as an escape
   hatch. Each gets a name that says what it is rather than what it measures.
   -------------------------------------------------------------------------- */

/* The quiet aside under a feature paragraph: a caveat, a proof point, or a
   limit worth stating but not worth the same weight as the claim.
   The compound selector is load-bearing: `.feature__body p` is 0,1,1 and a
   bare `.note` is 0,1,0, so the lead size would win inside a feature and the
   aside would come out the same weight as the claim it qualifies. */
.feature__body .note,
.note {
  font-size: var(--size-small);
  color: var(--text-quiet);
  line-height: 1.5;
}

/* The line that closes an argument section and hands off to the next. */
.section__closer {
  margin-top: var(--space-4);
  max-width: 40rem;
}

/* The hazard sentence, set as evidence rather than body copy. */
.pullquote {
  margin-top: var(--space-3);
}

.pullquote p {
  font-size: var(--size-body);
  color: var(--text);
}

.device-cluster--spaced {
  margin-bottom: var(--space-5);
}

.promise__head {
  margin-bottom: 0;
}

.promise__lead {
  margin-top: var(--space-2);
}

.promise__more {
  margin-top: var(--space-4);
  font-size: var(--size-small);
}

.signup--block {
  max-width: none;
}

.signup__lead {
  margin-top: var(--space-2);
}

.faq__more {
  margin-top: var(--space-4);
  text-align: center;
}

/* --------------------------------------------------------------------------
   17. MOTION

   One entrance, 420ms, and it is switched off entirely under Reduce Motion by
   the global rule in section 1. Nothing on this site animates on a loop.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
  .reveal {
    animation: reveal var(--dur-slow) var(--ease-out) both;
    animation-timeline: view();
    animation-range: entry 0% cover 22%;
  }

  @supports not (animation-timeline: view()) {
    .reveal {
      animation: none;
    }
  }
}

@keyframes reveal {
  from {
    opacity: 0;
    translate: 0 18px;
  }
  to {
    opacity: 1;
    translate: 0 0;
  }
}

/* --------------------------------------------------------------------------
   18. PRINT. The legal pages get printed and filed. Make that work.
   -------------------------------------------------------------------------- */

@media print {
  .site-header,
  .site-footer__grid,
  .theme-toggle,
  .skip-link {
    display: none;
  }

  body {
    background: #fff;
    color: #000;
    font-size: 11pt;
  }

  .doc {
    max-width: none;
    padding-block: 0;
  }

  .doc a::after {
    content: " (" attr(href) ")";
    font-size: 9pt;
    color: #444;
  }
}
