/* ==========================================================================
   BASE  ·  reset, the page, text roles, layout helpers, icons, focus
   Rules that hold for the whole app (the owner's list): no scrollbars anywhere, text selectable only where it is content (chat, letters, inputs),
   a visible focus ring, 44 px targets, nothing flashes white, nothing scrolls sideways. Type is SPEC 4: rem sizes, unitless line heights, lining figures, no synthesised weights.
   ========================================================================== */
*, *::before, *::after { box-sizing: border-box; }

html {
  background-color: var(--hl-bg);           /* the night, before any other CSS has run: never a white flash */
  color-scheme: dark;
  overscroll-behavior-y: contain;           /* no browser pull-to-refresh or glow: the app draws its own (ui/pull-to-refresh.js) */
  -webkit-tap-highlight-color: transparent;
  font-synthesis: none;                     /* a weight or a slant the face does not have is never faked */
  font-variant-numeric: lining-nums;        /* Playfair's default figures are old-style; the `font` shorthand resets this, so every Playfair rule says it again */
  scroll-padding-bottom: calc(var(--hl-tab-h) + var(--hl-safe-bottom) + var(--hl-dock-h) + var(--hl-fade-h));       /* a focused or anchored control is never left under a bar (WCAG 2.4.11); the shell sets --hl-tab-h and --hl-dock-h */
  scroll-padding-top: calc(var(--hl-safe-top) + var(--hl-sp-8));          /* ... nor under the strip of sky the shell draws as tall as the top inset (a notch), nor flush with the window's top edge */
}
body { margin: 0; min-height: 100vh; min-height: 100dvh; background-color: var(--hl-bg); overflow-x: hidden; }
@supports (overflow: clip) { body { overflow-x: clip; } }

/* ---- text size: the person's own setting is honoured (sizes are in rem, and no engine is told to keep text at 100%); only iOS Safari, which would inflate text when the phone turns sideways, is told not to */
@supports (-webkit-touch-callout: none) { html { -webkit-text-size-adjust: 100%; } }

/* ---- no scrollbars anywhere (a global rule). Things still scroll; they just do not draw a bar. */
:root, * { scrollbar-width: none; -ms-overflow-style: none; }
*::-webkit-scrollbar { display: none; width: 0; height: 0; background: transparent; }

h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd { margin: 0; }
h1, h2, h3, h4, h5, h6 { font: inherit; }
ul, ol { margin: 0; padding: 0; list-style: none; }
a { color: inherit; text-decoration: none; }
i { font-style: normal; }                   /* an empty <i> is a dot here, never an italic: it must not ask for the 50 KB italic file */
button, input, textarea, select { font: inherit; color: inherit; margin: 0; letter-spacing: inherit; }
button { padding: 0; border: 0; background: none; border-radius: 0; cursor: pointer; -webkit-appearance: none; appearance: none; }
img, svg, video, canvas { display: block; max-width: 100%; }
img { height: auto; }
[hidden] { display: none !important; }
:where(a, button, [role="button"], [role="tab"], [role="switch"], [role="radio"], input, select, textarea, label, summary) { touch-action: manipulation; }

/* ---- the app root (put class="hl-app" on <body>): the night with its sky (the sky eases from --hl-sky-top into the night over 420 px, and the grain dithers it so it does not band) */
.hl-app {
  min-height: 100vh; min-height: 100dvh;
  background: var(--hl-grain-night) 0 0 / 128px 128px, linear-gradient(180deg, var(--hl-sky-top) 0, var(--hl-bg) 420px) 0 0 / 100% 420px no-repeat, var(--hl-bg);
  color: var(--hl-text);
  font: 400 var(--hl-t-body-size) / var(--hl-t-body-lh) var(--hl-font-ui);
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
  /* the interface is not text to copy: chrome is not selectable, content opts in with .hl-selectable (chat bubbles, letters) and inputs always are */
  -webkit-user-select: none; user-select: none; -webkit-touch-callout: none;
}
.hl-selectable, .hl-selectable *, .hl-msg__bubble, .hl-msg__bubble *, .hl-paper, .hl-paper *, input, textarea { -webkit-user-select: text; user-select: text; }
.hl-app ::selection { background: rgba(255, 210, 122, .35); }

/* ---- focus: ONE ring for everything that can take it: 2 px Lantern Gold, 3 px off. Where a parent would clip it (a tab, a segment, a face option, a link at a sheet's foot) the offset is negative; on paper the ring is ink
   (gold is 1.41:1 on it); the street, the ticket and the PIN draw theirs in components.css and paper.css. What takes focus only from the program (a heading, the main area) is not a control and has none. */
:where(a, button, input, textarea, select, summary, [role="radio"], [role="tab"], [tabindex]:not([tabindex="-1"])):focus-visible { outline: var(--hl-focus); outline-offset: 3px; }
:where(.hl-tab, .hl-seg__item, .hl-avopt, .hl-link-ink):focus-visible { outline-offset: -4px; }
:where(a, button, input, textarea, select, summary, [role="radio"], [role="tab"]).is-focus { outline: var(--hl-focus); outline-offset: 3px; }          /* the style guide forces the look of the focus ring with .is-focus (the same ring, so a component states nothing of its own) */
:where(.hl-tab, .hl-seg__item, .hl-avopt, .hl-link-ink).is-focus { outline-offset: -4px; }
.hl-app :focus:not(:focus-visible) { outline: none; }
.hl-app :is(h1, h2, h3, h4, h5, h6, main, section, article, div, [data-screen-heading])[tabindex="-1"]:focus-visible { outline: none; }

.hl-container { width: 100%; max-width: var(--hl-content-max); margin-inline: auto; padding-inline: max(var(--hl-gutter), var(--hl-safe-left)) max(var(--hl-gutter), var(--hl-safe-right)); }
.hl-stack { display: flex; flex-direction: column; gap: var(--hl-sp-12); }
.hl-stack--lg { gap: var(--hl-sp-24); }
.hl-cluster { display: flex; flex-wrap: wrap; align-items: center; gap: var(--hl-sp-8); }
.hl-grid-2 { display: grid; gap: var(--hl-sp-12); grid-template-columns: 1fr; }
@media (min-width: 640px) { .hl-grid-2 { grid-template-columns: 1fr 1fr; } }
.hl-sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }

/* ---- text roles (SPEC 4: use the class, or read the --hl-t-* tokens). The old names stay as aliases of the new roles (title-1 = title, title-2 = heading, body-small = body-s, label-caps = label, numeral-big = figure-xl). */
.hl-t-display, .hl-t-title, .hl-t-title-1, .hl-t-heading, .hl-t-title-2, .hl-t-figure-xl, .hl-t-numeral-big { font-family: var(--hl-font-display); font-weight: 400; font-variant-numeric: lining-nums; text-wrap: balance; }
.hl-t-headline, .hl-t-body, .hl-t-body-s, .hl-t-body-small, .hl-t-caption, .hl-t-label, .hl-t-label-caps, .hl-t-figure { font-family: var(--hl-font-ui); }
.hl-t-display { font-size: var(--hl-t-display-size); line-height: var(--hl-t-display-lh); letter-spacing: -.01em; }
.hl-t-title, .hl-t-title-1 { font-size: var(--hl-t-title-size); line-height: var(--hl-t-title-lh); }
.hl-t-heading, .hl-t-title-2 { font-size: var(--hl-t-heading-size); line-height: var(--hl-t-heading-lh); }
.hl-t-headline { font-weight: 600; font-size: var(--hl-t-headline-size); line-height: var(--hl-t-headline-lh); letter-spacing: .005em; }
.hl-t-body { font-weight: 400; font-size: var(--hl-t-body-size); line-height: var(--hl-t-body-lh); text-wrap: pretty; }
.hl-t-body-s, .hl-t-body-small { font-weight: 500; font-size: var(--hl-t-body-s-size); line-height: var(--hl-t-body-s-lh); letter-spacing: .005em; text-wrap: pretty; }
.hl-t-caption { font-weight: 500; font-size: var(--hl-t-caption-size); line-height: var(--hl-t-caption-lh); letter-spacing: .01em; }
.hl-t-label, .hl-t-label-caps { font-weight: 700; font-size: var(--hl-t-label-size); line-height: var(--hl-t-label-lh); letter-spacing: .16em; text-transform: uppercase; }
.hl-t-figure { font-weight: 600; font-size: var(--hl-t-figure-size); line-height: var(--hl-t-figure-lh); font-variant-numeric: tabular-nums lining-nums; }
.hl-t-figure-xl, .hl-t-numeral-big { font-family: var(--hl-font-ui); font-weight: 300; font-size: var(--hl-t-figure-xl-size); line-height: var(--hl-t-figure-xl-lh); letter-spacing: -.02em; font-variant-numeric: tabular-nums lining-nums; }
.hl-muted { color: var(--hl-text-muted); }
.hl-gold { color: var(--hl-accent-gold); }
.hl-tnum { font-variant-numeric: tabular-nums lining-nums; }
.hl-nowrap { white-space: nowrap; }          /* (the utility: never wraps) */
.hl-glue { display: inline-block; max-width: 100%; white-space: normal; }          /* ui/_internal.js glue(): the last two words of a line stay together while they fit (an atom that wraps as a whole), and wrap inside their own box when they cannot: at 200 percent text on a 320 px phone "for playing." was 141 px in a 138 px column */

/* ---- line icons: a 24 px grid, round caps and joins, ONE rendered stroke of 1.5 px at every size (36 / size in user units: 1.5 at 24, 2 at 18, 2.25 at 16). <svg class="hl-icon"><use href="#hl-i-NAME"/></svg> */
.hl-icon { width: 24px; height: 24px; flex: none; display: block; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.hl-icon--sm { width: 18px; height: 18px; stroke-width: 2; }
.hl-icon--xs { width: 16px; height: 16px; stroke-width: 2.25; }
.hl-icon--lg { width: 32px; height: 32px; stroke-width: 1.125; }
.hl-icon--fill { fill: currentColor; stroke: none; }          /* the one filled glyph: the play triangle (14 px) */

/* (Windows high-contrast mode is at the end of components.css: it has to come after the component rules it overrides) */
