/* ==========================================================================
   SILNS — global.css

   Loaded first on every page. Design tokens, the four themes, typography,
   the logo lockups, and the controls shared everywhere: buttons, inputs,
   notices, focus rings, the spinner.

   Nothing here is page-specific. app.css, marketing.css and display.css all
   load after this and build on it.

   No width breakpoints, on purpose: the type and spacing scales use clamp()
   so they respond continuously rather than in steps. The shared ladder used
   by the other two files is:

       26rem   past the narrowest phones
       30rem   large phones and up
       34rem   phablets and up
       48rem   tablets and up
       62rem   desktop and up
   ========================================================================== */

/* --- Reset ------------------------------------------------------------- */

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

* { margin: 0; }

html {
  -webkit-text-size-adjust: 100%;
  -moz-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  min-height: 100vh;
  min-height: 100dvh;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: 1.6;
  color: var(--ink);
  background: var(--bg);
  transition: background-color var(--calm-transition), color var(--calm-transition);
}

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

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

/* --- Tokens ------------------------------------------------------------ */

:root {
  /* Warmth ladder ----------------------------------------------------- */
  --void: #0b0a09;
  --umber: #16130f;
  --ash: #2a251e;
  --stone: #6b6459;
  --bone: #ede8df;
  --paper: #f5f3ef;

  /* The one accent, and the functional colours ------------------------ */
  --sage: #7e9384;
  --slate: #7b8794;
  --plum: #8c7089;
  --alert: #a35c66;

  /* Type --------------------------------------------------------------- */
  --font-body: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-display: "Helvetica Neue", Inter, system-ui, -apple-system, "Segoe UI", Arial, sans-serif;
  --font-serif: ui-serif, Georgia, "Iowan Old Style", "Times New Roman", serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", "Cascadia Mono", Menlo, monospace;

  --text-xs: 0.75rem;
  --text-sm: 0.875rem;
  --text-base: 1rem;
  --text-lg: clamp(1.0625rem, 0.98rem + 0.4vw, 1.1875rem);
  --text-xl: clamp(1.375rem, 1.2rem + 0.85vw, 1.75rem);
  --text-2xl: clamp(1.875rem, 1.5rem + 1.8vw, 2.75rem);
  --text-3xl: clamp(2.5rem, 1.7rem + 3.6vw, 4.5rem);

  /* Eyebrows and labels share one treatment across the whole product. */
  --eyebrow-size: 0.6875rem;
  --eyebrow-tracking: 0.24em;

  /* Space -------------------------------------------------------------- */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-7: 3rem;
  --space-8: 4rem;
  --space-9: clamp(4.5rem, 3rem + 7vw, 9rem);

  --radius-sm: 3px;
  --radius: 6px;
  --radius-lg: 14px;
  --radius-pill: 999px;

  --measure: 34rem;
  --page-max: 68rem;

  /* Motion ------------------------------------------------------------- */
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  /* Changes are slow on purpose. Nothing on screen should be noticed as
     never caught out of the corner of the eye. */
  --calm-transition: 2400ms cubic-bezier(0.4, 0, 0.2, 1);
  --ui-transition: 220ms var(--ease);

  color-scheme: dark;
}

/* --- Themes ------------------------------------------------------------- */

:root,
[data-theme="dark"] {
  --bg: #0e0d0c;
  --surface: #171512;
  --surface-raised: #1e1b17;
  --line: #2a251e;
  --line-strong: #3a3329;
  --ink: #ede8df;
  --ink-muted: #8a8175;
  --ink-faint: #5f584e;
  --timer-ink: var(--ink);
  --accent: #88a5a7;
  --accent-strong: #88a5a7;
  --accent-ink: #0c1414;
  --focus: #88a5a7;
  color-scheme: dark;
}

[data-theme="light"] {
  --bg: #e9e7e1;
  --surface: #f5f3ef;
  --surface-raised: #fffefb;
  --line: #d3cfc5;
  --line-strong: #b8b2a5;
  --ink: #1a1815;
  --ink-muted: #6b6459;
  --ink-faint: #938d81;
  --timer-ink: var(--ink);
  --accent: #557375;
  --accent-strong: #435a5c;
  --accent-ink: #fffefb;
  --focus: #435a5c;
  color-scheme: light;
}

/* Low light: no whites at all. A treatment room at 8pm with one lamp on.
   Everything is warm, and the brightest thing on screen is the time. */
[data-theme="lowlight"] {
  --bg: #080706;
  --surface: #0e0c0a;
  --surface-raised: #14100c;
  --line: #1e1813;
  --line-strong: #2c241a;
  --ink: #c2996c;
  --ink-muted: #7a6047;
  --ink-faint: #533f2e;
  --timer-ink: #d8a268;
  --accent: #d8a268;
  --accent-strong: #d8a268;
  --accent-ink: #0e0c0a;
  --focus: #d8a268;
  color-scheme: dark;
}

/* --- Typography --------------------------------------------------------- */

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

h1 { font-size: var(--text-3xl); }
h2 { font-size: var(--text-2xl); }
h3 { font-size: var(--text-xl); }

p { text-wrap: pretty; }

a {
  color: inherit;
  text-decoration-color: var(--line-strong);
  text-underline-offset: 0.25em;
  transition: text-decoration-color var(--ui-transition);
}

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

/* The tagline. The only serif in the product, used twice, and always italic. */
.tagline {
  font-family: var(--font-serif);
  font-style: italic;
  letter-spacing: 0.01em;
  color: var(--ink-muted);
}

.eyebrow {
  font-size: var(--eyebrow-size);
  letter-spacing: var(--eyebrow-tracking);
  text-transform: uppercase;
  color: var(--ink-faint);
  font-weight: 500;
}

.lede {
  font-size: var(--text-lg);
  color: var(--ink-muted);
  max-width: var(--measure);
}

/* The wordmark. Wide tracking, because the name is a held breath.
   Letter-spacing leaves a gap after the final S; the negative end margin
   removes it so the mark optically aligns with anything beside or below it. */
.wordmark {
  font-family: var(--font-display);
  font-weight: 300;
  letter-spacing: 0.34em;
  margin-inline-end: -0.34em;
  text-transform: uppercase;
  color: var(--ink);
  text-decoration: none;
}

/* The lockup: the mark and the name set as one object. Sized in em so both
   halves scale together wherever it is placed, and drawn in currentColor so
   it follows the theme rather than fighting it. */
.brand {
  display: inline-flex;
  align-items: center;
  color: var(--ink);
  text-decoration: none;
}

/* --- The logo ------------------------------------------------------------
   One piece of markup, three variants. Every context picks exactly one:

     .brand--full     mark + name + descriptor. The primary lockup, for
                      anywhere with room to breathe — the hero, the gates,
                      the footer, the share card.
     .brand--compact  mark + name. For bars and any tight single-line row,
                      where a descriptor would be four pixels tall.
     .brand--mark     the mark on its own. For anything too small for words.

   All three scale from --lock, which is the wordmark's size. Set that one
   value per context and the mark, the name, the line and the gaps follow. */

.brand--full,
.brand--compact,
.brand--mark { --lock: 1.25rem; }

.brand-mark {
  flex: none;
  width: calc(var(--lock) * 2.15);
  height: calc(var(--lock) * 2.15);
}

.brand-text {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: calc(var(--lock) * 0.3);
  text-align: left;
}

.brand--full { gap: calc(var(--lock) * 0.58); }

.brand--full .wordmark,
.brand--compact .wordmark { font-size: var(--lock); }

/* Never allowed to wrap: a descriptor that breaks over two lines stops being
   a descriptor and starts being a sentence. */
.brand-desc {
  font-family: var(--font-display);
  font-size: calc(var(--lock) * 0.42);
  font-weight: 400;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-muted);
  line-height: 1;
  white-space: nowrap;
}

/* Compact drops the line, and brings the mark down to sit beside one line of
   type rather than towering over two. */
.brand--compact .brand-desc { display: none; }
.brand--compact { gap: calc(var(--lock) * 0.44); }
.brand--compact .brand-mark {
  width: calc(var(--lock) * 1.5);
  height: calc(var(--lock) * 1.5);
}

/* Mark alone. display:none rather than [hidden], so it leaves the
   accessibility tree and no reader announces a name that is not shown. */
.brand--mark .brand-text { display: none; }

/* --- Controls ----------------------------------------------------------- */

.btn {
  --btn-bg: transparent;
  --btn-ink: var(--ink);
  --btn-line: var(--line-strong);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: 0.7em 1.4em;
  min-height: 44px; /* comfortable with oiled hands and on a tablet */
  border: 1px solid var(--btn-line);
  border-radius: var(--radius-pill);
  background: var(--btn-bg);
  color: var(--btn-ink);
  font-size: var(--text-sm);
  letter-spacing: 0.02em;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--ui-transition), border-color var(--ui-transition),
              color var(--ui-transition), opacity var(--ui-transition);
}

.btn:hover:not(:disabled) { border-color: var(--ink-muted); }

.btn:disabled { opacity: 0.4; cursor: not-allowed; }

.btn--primary {
  --btn-bg: var(--accent);
  --btn-ink: var(--accent-ink);
  --btn-line: var(--accent);
  font-weight: 500;
}

.btn--primary:hover:not(:disabled) { filter: brightness(1.08); border-color: var(--accent); }

.btn--quiet {
  --btn-line: transparent;
  --btn-ink: var(--ink-muted);
  padding-inline: 0.8em;
}

.btn--quiet:hover:not(:disabled) { --btn-ink: var(--ink); --btn-line: var(--line); }

.btn--danger { --btn-ink: var(--alert); --btn-line: color-mix(in srgb, var(--alert) 40%, transparent); }
.btn--danger:hover:not(:disabled) { --btn-line: var(--alert); }

.btn--block { width: 100%; }

.btn--lg { padding: 0.95em 1.9em; font-size: var(--text-base); }

/* Google's mark stays its own colours; the button around it is ours. */
.btn--google {
  --btn-bg: var(--surface-raised);
  --btn-ink: var(--ink);
  --btn-line: var(--line-strong);
  font-weight: 500;
}

.btn--google .google-mark { width: 18px; height: 18px; flex: none; }

/* --- Forms -------------------------------------------------------------- */

.field { display: flex; flex-direction: column; gap: var(--space-2); }

.field > label,
.label {
  font-size: var(--text-sm);
  color: var(--ink-muted);
}

.input,
select.input {
  padding: 0.65em 0.85em;
  min-height: 44px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--ink);
  transition: border-color var(--ui-transition);
}

.input:hover { border-color: var(--line-strong); }

select.input {
  appearance: none;
  padding-right: 2.2em;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 1.1em) 55%, calc(100% - 0.75em) 55%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}

input[type="range"] { accent-color: var(--accent); }

/* A switch, sized for a thumb. */
.switch {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-3) 0;
  cursor: pointer;
}

.switch input { position: absolute; opacity: 0; pointer-events: none; }

.switch-track {
  position: relative;
  flex: none;
  width: 44px;
  height: 26px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--line-strong);
  background: var(--surface);
  transition: background-color var(--ui-transition), border-color var(--ui-transition);
}

.switch-track::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--ink-muted);
  transition: transform var(--ui-transition), background-color var(--ui-transition);
}

.switch input:checked + .switch-track { background: var(--accent); border-color: var(--accent); }
.switch input:checked + .switch-track::after { transform: translateX(18px); background: var(--accent-ink); }
.switch input:focus-visible + .switch-track { outline: 2px solid var(--focus); outline-offset: 2px; }

.switch-text { display: flex; flex-direction: column; gap: 2px; }
.switch-hint { font-size: var(--text-sm); color: var(--ink-faint); }

/* --- Focus -------------------------------------------------------------- */

:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

:focus:not(:focus-visible) { outline: none; }

.skip-link {
  position: absolute;
  top: var(--space-3);
  left: var(--space-3);
  z-index: 100;
  padding: var(--space-3) var(--space-4);
  background: var(--surface-raised);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  transform: translateY(-200%);
  transition: transform var(--ui-transition);
}

.skip-link:focus { transform: translateY(0); }

/* --- Layout helpers ----------------------------------------------------- */

.page {
  width: min(100% - 2 * var(--space-5), var(--page-max));
  margin-inline: auto;
}

.rule { border: 0; border-top: 1px solid var(--line); }

.stack { display: flex; flex-direction: column; }
.stack-3 { gap: var(--space-3); }
.stack-4 { gap: var(--space-4); }
.stack-5 { gap: var(--space-5); }
.stack-6 { gap: var(--space-6); }

.row { display: flex; align-items: center; gap: var(--space-3); }
.row-between { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); }
.wrap { flex-wrap: wrap; }

.muted { color: var(--ink-muted); }
.faint { color: var(--ink-faint); }
.center { text-align: center; }

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

[hidden] { display: none !important; }

/* --- Price ------------------------------------------------------------- */

/* The price appears in several places and always reads the same way:
   the number is the statement, "once" is the promise. */
.price {
  display: inline-flex;
  align-items: baseline;
  gap: 0.4em;
  font-family: var(--font-display);
}

.price-figure {
  font-size: var(--text-2xl);
  font-weight: 200;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

.price-term {
  font-size: var(--text-sm);
  letter-spacing: 0.08em;
  text-transform: lowercase;
  color: var(--ink-muted);
}

/* --- Notices ------------------------------------------------------------ */

.notice {
  padding: var(--space-4);
  border: 1px solid var(--line);
  border-left: 2px solid var(--ink-faint);
  border-radius: 0 var(--radius) var(--radius) 0;
  background: var(--surface);
  font-size: var(--text-sm);
  color: var(--ink-muted);
}

.notice--error { border-left-color: var(--alert); color: var(--ink); }
.notice--good { border-left-color: var(--sage); }

/* An offline banner that states a fact and does not apologise. */
.connection-banner {
  position: fixed;
  inset-inline: 0;
  bottom: 0;
  z-index: 60;
  padding: var(--space-3) var(--space-5);
  background: var(--surface-raised);
  border-top: 1px solid var(--line-strong);
  font-size: var(--text-sm);
  color: var(--ink-muted);
  text-align: center;
}

/* --- Spinner ------------------------------------------------------------ */

.spinner {
  width: 18px;
  height: 18px;
  border: 1.5px solid var(--line-strong);
  border-top-color: var(--ink-muted);
  border-radius: 50%;
  animation: spin 900ms linear infinite;
}

@keyframes spin { to { transform: rotate(360deg); } }

/* --- Reduced motion ----------------------------------------------------- */

/* SILNS never flashes. With reduced motion on it does not move at all:
   changes still happen, they simply arrive instantly instead of fading. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --calm-transition: 1ms linear;
    --ui-transition: 1ms linear;
  }

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