/* ══════════════════════════════════════════════════════════════════════════════════════════════════════════════
   App Manager for Microsoft Entra — the public page.

   THE VALUES BELOW ARE A TRANSCRIPTION OF `brand/tokens/tokens.json`, which the brand package declares as its own
   source of truth. They are transcribed rather than imported because this page has no build step and must open from
   the filesystem — and transcription is exactly how a palette drifts, so it is held by a test:
   `ClientApp/src/themes/theme/brand.test.ts` reads this file and fails when a value here stops matching the tokens.
   Change a colour in the package, not here.

   TWO SCHEMES, THREE STATES. `data-color-scheme` is stamped on <html> when the reader has chosen; with nothing
   stamped only `prefers-color-scheme` separates the two, which is the state most visitors arrive in. Every colour is
   therefore defined on bare `:root` and only REDEFINED in the two dark blocks — a colour whose single definition
   lives inside a media query never applies to a reader who has chosen light on a dark system.

   AND A THIRD PLACE: `.stage` re-declares the same dark values, because the hero is navy in BOTH schemes. It is a
   block of tokens rather than a block of hard-coded colours so that everything inside it — buttons, the lockup, the
   eyebrow — keeps reading the same variable names it reads everywhere else. The test holds that block too.
   ══════════════════════════════════════════════════════════════════════════════════════════════════════════════ */

:root {
  /* brand — scheme-independent accents, plus the three the lockup switches */
  --brand-navy: #0B2545;
  --brand-sky: #38BDF8;
  --brand-mint: #34D399;
  --brand-amber: #FBBF24;
  --brand-plate: #0B2545;
  --brand-wordmark: #0B2545;
  --brand-descriptor: #5C6470;

  /* the register's own semantics, used by the board — the same five the expiry chart reads */
  --chart-overdue: #F87171;
  --chart-within30: #FBBF24;
  --chart-later: #38BDF8;
  --chart-managed: #34D399;
  --chart-cannot-expire: #CBD5E1;

  /* light */
  --primary-lighter: #F0F9FF;
  --primary-light: #7DD3FC;
  --primary-fill: #38BDF8;
  --primary-main: #0284C7;
  --primary-dark: #075985;
  --primary-contrast: #FFFFFF;
  --success-lighter: #ECFDF5;
  --success-fill: #34D399;
  --success-main: #047857;
  --warning-dark: #B45309;
  /* Links on the page's own ground, as opposed to text inside a button. NOT a new colour — an alias that resolves
     to `primary.dark` in light and `primary.main` in dark, because `primary.main` is 3.88:1 on the light ground and
     fails AA at body sizes while looking perfectly ordinary. It exists so the next link added to this page cannot
     repeat that; the footer's link had it and nobody noticed until the contrast was measured. */
  --link: #075985;
  --bg-default: #F7F9FC;
  --bg-paper: #FFFFFF;
  --divider: #EEF2F6;
  --border: #E2E8F0;
  --text-primary: #0B2545;
  --text-secondary: #5C6470;
  --text-muted: #8A94A4;

  /* shape — tokens.shape */
  --radius-card: 10px;
  --radius-control: 8px;

  /* type — tokens.typography.scale. The two DISPLAY sizes below are this page's own and are deliberately not in the
     package: the application's scale tops out at 30px because it is read at a desk on a dense screen, and a public
     page is read from further away with nothing else on it. Everything else is the token. */
  --fs-hero: clamp(2.25rem, 1.1rem + 4.9vw, 4.25rem);
  --fs-lead: clamp(1rem, 0.94rem + 0.3vw, 1.1875rem);
  --fs-h3: 1.875rem;   /* 30 */
  --fs-h4: 1.5rem;     /* 24 */
  --fs-h5: 1.125rem;   /* 18 */
  --fs-h6: 0.9375rem;  /* 15 */
  --fs-body: 0.9375rem;
  --fs-body2: 0.875rem;
  --fs-caption: 0.75rem;
  --fs-overline: 0.6875rem;

  --shadow-card: 0 1px 2px rgb(11 37 69 / 6%);
  --wrap: 1120px;

  color-scheme: light;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-color-scheme="light"]) {
    --link: #7DD3FC;
    --brand-plate: #16365E;
    --brand-wordmark: #FFFFFF;
    --brand-descriptor: #93A4BC;
    --chart-cannot-expire: #3F5570;
    --primary-lighter: #0B2B40;
    --primary-light: #38BDF8;
    --primary-fill: #38BDF8;
    --primary-main: #7DD3FC;
    --primary-dark: #0284C7;
    --primary-contrast: #071626;
    --success-lighter: #0C3A2E;
    --success-fill: #34D399;
    --success-main: #6EE7B7;
    --bg-default: #071626;
    --bg-paper: #0C2136;
    --divider: #16324B;
    --border: #1E3D5A;
    --text-primary: #E8EEF6;
    --text-secondary: #A3B2C6;
    --text-muted: #7C8CA3;
    --shadow-card: 0 1px 2px rgb(0 0 0 / 24%);
    color-scheme: dark;
  }
}

:root[data-color-scheme="dark"] {
  --link: #7DD3FC;
  --brand-plate: #16365E;
  --brand-wordmark: #FFFFFF;
  --brand-descriptor: #93A4BC;
  --chart-cannot-expire: #3F5570;
  --primary-lighter: #0B2B40;
  --primary-light: #38BDF8;
  --primary-fill: #38BDF8;
  --primary-main: #7DD3FC;
  --primary-dark: #0284C7;
  --primary-contrast: #071626;
  --success-lighter: #0C3A2E;
  --success-fill: #34D399;
  --success-main: #6EE7B7;
  --bg-default: #071626;
  --bg-paper: #0C2136;
  --divider: #16324B;
  --border: #1E3D5A;
  --text-primary: #E8EEF6;
  --text-secondary: #A3B2C6;
  --text-muted: #7C8CA3;
  --shadow-card: 0 1px 2px rgb(0 0 0 / 24%);
  color-scheme: dark;
}

/* ── the face ─────────────────────────────────────────────────────────────────────────────────────────────────
   Inter Variable, self-hosted: the same file the application loads, copied from @fontsource-variable/inter. NOT a
   font CDN — a public page for a European customer should not make every visitor's browser announce itself to a
   third party, and a CDN that fails leaves the page in a system sans nobody chose.
   `latin-ext` carries č ď ě ň ř š ť ů ž; without it the Czech text falls back mid-sentence, one glyph at a time. */
@font-face {
  font-family: 'Inter Variable';
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url('assets/fonts/inter-latin-wght-normal.woff2') format('woff2-variations');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
    U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter Variable';
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url('assets/fonts/inter-latin-ext-wght-normal.woff2') format('woff2-variations');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF,
    U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* JetBrains Mono is the brand's DATA face (`tokens.typography.fontFamilyMono`) and nothing in this identity had
   used it yet. It appears in exactly one place — the countdown board — because that is the one thing on the page
   that is a reading of the product's data rather than a sentence about it. */
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url('assets/fonts/jetbrains-mono-latin-400-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2000-206F, U+20AC, U+2122, U+2212;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url('assets/fonts/jetbrains-mono-latin-ext-400-normal.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+1E00-1E9F, U+2C60-2C7F,
    U+A720-A7FF;
}

/* ── baseline ─────────────────────────────────────────────────────────────────────────────────────────────── */

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

body {
  margin: 0;
  font-family: 'Inter Variable', system-ui, -apple-system, 'Segoe UI', sans-serif;
  font-size: var(--fs-body);
  line-height: 1.6;
  color: var(--text-primary);
  background: var(--bg-default);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { margin: 0; font-weight: 500; line-height: 1.25; text-wrap: balance; }
p { margin: 0; }
ul, ol, dl, dd { margin: 0; padding: 0; }
li { list-style: none; }

a { color: var(--primary-main); }

/* The application's own focus ring (`themes/GlobalStyles.tsx`), so a keyboard reader arriving here from the product
   sees the same signal. `:focus-visible`, not `:focus` — a mouse click should not ring what it just pressed. */
:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--primary-lighter);
  border-color: var(--primary-main);
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation: none !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

html { scroll-behavior: smooth; }

.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

.icon { width: 1em; height: 1em; fill: currentColor; flex: none; }

.wrap { width: 100%; max-width: var(--wrap); margin-inline: auto; padding-inline: clamp(1.25rem, 4vw, 2.5rem); }

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 10;
  padding: 0.75rem 1rem;
  background: var(--bg-paper);
  border: 1px solid var(--border);
  border-radius: var(--radius-control);
}
.skip:focus { left: 1rem; top: 1rem; }

/* ── language: both catalogues are in the markup, one is hidden ───────────────────────────────────────────────
   No JavaScript rewrites a single sentence — the page carries both, `lang` marks which is which (so a screen reader
   and a translator both read it correctly), and the attribute on <html> decides. It also means the page still says
   something if the script never runs. */
html[data-lang="cs"] [lang="en"],
html[data-lang="en"] [lang="cs"] { display: none; }

/* ══ THE STAGE ════════════════════════════════════════════════════════════════════════════════════════════════
   Navy in both schemes, and a TOKEN BLOCK rather than a set of hard-coded colours: everything inside goes on
   reading `--text-primary`, `--primary-main`, `--brand-wordmark` and so on, and simply gets the dark values. That
   is what stops the lockup rendering a navy wordmark on navy — which does not look broken, it looks absent. */
.stage {
  --brand-plate: #16365E;
  --brand-wordmark: #FFFFFF;
  --brand-descriptor: #93A4BC;
  --primary-lighter: #0B2B40;
  --primary-main: #7DD3FC;
  --primary-dark: #0284C7;
  --primary-contrast: #071626;
  --bg-paper: #0C2136;
  --border: #1E3D5A;
  --text-primary: #E8EEF6;
  --text-secondary: #A3B2C6;
  --text-muted: #7C8CA3;

  position: relative;
  overflow: hidden;
  color: var(--text-primary);
  background: var(--brand-navy);
}

/* Ambient light from three of the four accents, low and wide, kept well away from the text: the headline sits on
   plain navy and is measured there, not against a gradient that happens to be pale under it. */
.stage::before {
  content: '';
  position: absolute;
  inset: -22% -10% auto -10%;
  height: 92%;
  background:
    radial-gradient(38% 55% at 22% 42%, rgb(56 189 248 / 24%), transparent 70%),
    radial-gradient(30% 45% at 74% 28%, rgb(52 211 153 / 16%), transparent 70%),
    radial-gradient(26% 40% at 54% 78%, rgb(251 191 36 / 12%), transparent 70%);
  filter: blur(10px);
  pointer-events: none;
}

.chrome {
  position: relative;
  z-index: 1;
  display: flex;
  gap: 1rem;
  align-items: flex-start;
  justify-content: space-between;
  padding-top: clamp(1.5rem, 3vw, 2.5rem);
}

.lockup { display: block; line-height: 0; border-radius: var(--radius-control); }
.lockup svg { display: block; height: clamp(44px, 6vw, 60px); width: auto; }

.controls { display: flex; gap: 0.5rem; align-items: center; }

.langs { display: inline-flex; border: 1px solid var(--border); border-radius: var(--radius-control); overflow: hidden; }

.lang {
  padding: 0.25rem 0.625rem;
  font: inherit;
  font-size: var(--fs-caption);
  color: var(--text-secondary);
  background: transparent;
  border: 0;
  cursor: pointer;
}
.lang + .lang { border-left: 1px solid var(--border); }
.lang:hover { color: var(--text-primary); }
.lang[aria-pressed="true"] { color: var(--primary-main); background: var(--primary-lighter); }

.scheme {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  font-size: 1rem;
  color: var(--text-primary);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--radius-control);
  cursor: pointer;
}
.scheme:hover { color: var(--primary-main); }

.stage-inner {
  position: relative;
  z-index: 1;
  max-width: 54rem;
  padding-top: clamp(2.5rem, 6vw, 4.5rem);
  text-align: center;
  margin-inline: auto;
}

.eyebrow {
  margin-bottom: 1.125rem;
  font-size: var(--fs-overline);
  font-weight: 500;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--primary-main);
}

h1 {
  font-size: var(--fs-hero);
  line-height: 1.05;
  letter-spacing: -0.032em;
  color: #FFFFFF;
}

.lead { margin: 1.5rem auto 0; max-width: 52ch; font-size: var(--fs-lead); line-height: 1.6; color: var(--text-secondary); }

.actions { display: flex; flex-wrap: wrap; gap: 0.75rem; align-items: center; margin-top: 2.25rem; justify-content: center; }

.button {
  display: inline-flex;
  gap: 0.5rem;
  align-items: center;
  padding: 0.8125rem 1.375rem;
  font-size: var(--fs-h6);
  font-weight: 500;
  line-height: 1.4;
  text-decoration: none;
  border: 1px solid transparent;
  border-radius: var(--radius-control);
  transition: background-color 140ms ease, border-color 140ms ease, color 140ms ease;
}
.button .icon { font-size: 0.875em; }
.button.primary { color: var(--primary-contrast); background: var(--primary-main); }
.button.primary:hover { background: var(--primary-light); }
.button.quiet { color: var(--text-primary); background: transparent; border-color: var(--border); }
.button.quiet:hover { color: var(--primary-main); border-color: var(--primary-main); }

/* The product, tilted back and cropped by the fold — it reads as continuing below rather than as a picture pasted
   on. `perspective` on the wrapper and the rotation on the frame, so the tilt has depth instead of being a flat
   skew. One orchestrated entrance and nothing after it. */
.viewport { position: relative; z-index: 1; perspective: 2000px; margin-top: clamp(2.5rem, 5vw, 4rem); }

.frame {
  max-width: 1180px;
  margin: 0 auto;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 12px 12px 0 0;
  box-shadow: 0 -8px 80px -20px rgb(56 189 248 / 20%), 0 40px 80px -30px rgb(0 0 0 / 70%);
  transform-origin: top center;
  animation: settle 900ms cubic-bezier(0.16, 0.9, 0.3, 1) both;
  animation-delay: 200ms;
}
@keyframes settle {
  from { transform: rotateX(15deg) translateY(52px); opacity: 0; }
  to { transform: rotateX(6deg) translateY(0); opacity: 1; }
}
.frame img { display: block; width: 100%; height: auto; }

/* ── sections ─────────────────────────────────────────────────────────────────────────────────────────────── */

.band { padding-block: clamp(2.5rem, 5vw, 4rem); }
/* `.band > h2` is a CHILD selector, and the expiry section's heading stopped being a child the day that section
   became two columns and its heading moved inside a wrapper. It fell back to the browser's `h2` default — 22.5px
   against the 30 every other section heading uses — and nothing failed: a heading that is merely the wrong size
   still looks like a heading. Found by listing every rendered font size on the page and asking where 22.5 came
   from. */
.band > h2,
.board-section h2 { font-size: var(--fs-h3); letter-spacing: -0.015em; }

/* 62ch, not 46rem. At 15px that box measured 92 characters a line — half again the width at which the eye starts
   losing its place returning to the left margin. Measured, not eyeballed. */
.section-lead { max-width: 62ch; margin-top: 0.75rem; color: var(--text-secondary); }

/* ── the three things ─────────────────────────────────────────────────────────────────────────────────────── */

.pillars { display: grid; gap: clamp(1.5rem, 3vw, 2.5rem); grid-template-columns: 1fr; }
@media (min-width: 56rem) { .pillars { grid-template-columns: repeat(3, 1fr); } }

.pillars h2 { margin-top: 1rem; font-size: var(--fs-h4); letter-spacing: -0.01em; }
.pillars p { margin-top: 0.625rem; color: var(--text-secondary); }

/* The sign-in page's glyph plate: the palette's own `lighter` fill with `main` ink — the pairing the status chips
   use, so nothing here is a new visual pattern. */
.plate {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  font-size: 1.25rem;
  color: var(--primary-main);
  background: var(--primary-lighter);
  border-radius: var(--radius-control);
}

/* AFTER `.plate`, not before it. Same specificity, so the later rule wins — put this above and the base width
   silently overrides it, which is the third time that has happened in this file (`.shot-frame { margin: 0 }` ate
   the hero's bleed, and `.hero-inner`'s own max-width ate its alignment). A modifier goes below what it modifies. */
.plate-sm { width: 38px; height: 38px; font-size: 1.0625rem; }

/* ── the screenshot frames ────────────────────────────────────────────────────────────────────────────────── */

.shot-frame {
  margin: 2rem 0 0;
  overflow: hidden;
  background: var(--bg-paper);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  box-shadow: 0 24px 48px -24px rgb(11 37 69 / 22%), 0 2px 8px -2px rgb(11 37 69 / 8%);
}
:root[data-color-scheme="dark"] .shot-frame { box-shadow: 0 24px 48px -24px rgb(0 0 0 / 55%); }
@media (prefers-color-scheme: dark) {
  :root:not([data-color-scheme="light"]) .shot-frame { box-shadow: 0 24px 48px -24px rgb(0 0 0 / 55%); }
}

/* `height: auto` against the markup's width/height, so the aspect ratio is reserved before the file arrives and the
   page does not jump. */
.shot { display: block; width: 100%; height: auto; }

/* ── the change workflow, as counted steps ───────────────────────────────────────────────────────────────
   NUMBERED, and the numbers are information rather than decoration: the record is written BEFORE the change is
   applied, which is the claim the whole section rests on and is unreadable if the three are a set rather than a
   sequence. The chip is the register's own `lighter` fill with `fill` border and `main` ink — the status chip's
   anatomy, so this is not a new visual pattern. */
.steps { display: grid; gap: 2rem 2.5rem; grid-template-columns: 1fr; align-items: start; margin-top: 2rem; }
@media (min-width: 56rem) { .steps { grid-template-columns: repeat(3, 1fr); } }

.step {
  display: inline-grid;
  place-items: center;
  width: 28px;
  height: 28px;
  font-size: var(--fs-caption);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--primary-main);
  background: var(--primary-lighter);
  border: 1px solid var(--primary-fill);
  border-radius: var(--radius-control);
}

.steps h3 { margin-top: 0.875rem; font-size: var(--fs-h5); }
.steps p { margin-top: 0.5rem; font-size: var(--fs-body2); line-height: 1.65; color: var(--text-secondary); }

/* ── the expiry section: the sentence and the board side by side ───────────────────────────────────────────
   One column below 64rem, where a countdown board squeezed beside a paragraph is neither. */
.board-section { display: grid; gap: clamp(2rem, 4vw, 3.5rem); align-items: center; }
@media (min-width: 64rem) { .board-section { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } }
.board-section .section-lead { max-width: 40ch; }
.board-section .board { margin-top: 0; }

/* THE ONE ACTION IN THE MIDDLE OF THE PAGE. Between the hero's button and the demo panel at the foot there were
   5,400px with nothing to click — a reader persuaded here had to scroll to the end or back up. Deliberately quiet:
   a link, not a second button, because the loud one is in the hero and two loud ones make neither. The arrow moves
   on hover, which is the whole of its animation. */
.quiet-action { margin-top: 1.5rem; }
.quiet-action a {
  display: inline-flex;
  gap: 0.5rem;
  align-items: center;
  font-weight: 500;
  color: var(--link);
  text-decoration: none;
}
.quiet-action .icon { font-size: 0.8125em; transition: transform 140ms ease; }
.quiet-action a:hover { text-decoration: underline; }
.quiet-action a:hover .icon { transform: translateX(3px); }

/* ── the board ────────────────────────────────────────────────────────────────────────────────────────────────
   A departures board of real register rows. The mask belongs to the LIST and not to the whole box — put it on the
   box and it fades the column header along with the rows. */
.board {
  position: relative;
  height: 26rem;
  margin-top: 2rem;
  overflow: hidden;
  background: var(--bg-paper);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
}

.board-head {
  position: absolute;
  inset: 0 0 auto 0;
  z-index: 2;
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.875rem clamp(1rem, 2.5vw, 1.5rem);
  font-family: 'JetBrains Mono', ui-monospace, Menlo, monospace;
  font-size: var(--fs-overline);
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--text-secondary);
  background: var(--bg-paper);
  border-bottom: 1px solid var(--border);
}

.board-view {
  position: absolute;
  inset: 2.9rem 0 0 0;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(180deg, transparent, #000 9%, #000 84%, transparent);
  mask-image: linear-gradient(180deg, transparent, #000 9%, #000 84%, transparent);
}

/* The rows are written twice, so translating by exactly half returns to the start and the seam is invisible. */
.track { animation: drift 52s linear infinite; }
@keyframes drift { from { transform: translateY(0); } to { transform: translateY(-50%); } }

.row {
  display: flex;
  gap: 1rem;
  align-items: baseline;
  justify-content: space-between;
  padding: 0.5625rem clamp(1rem, 2.5vw, 1.5rem);
  font-family: 'JetBrains Mono', ui-monospace, Menlo, monospace;
  font-size: var(--fs-caption);
  border-top: 1px solid var(--divider);
}
.row .what { color: var(--text-primary); }
.row .who { display: block; margin-top: 0.125rem; font-size: var(--fs-overline); color: var(--text-secondary); }
.row .when { font-variant-numeric: tabular-nums; white-space: nowrap; text-align: right; }

.row.gone .when { color: var(--chart-overdue); }
.row.soon .when { color: var(--warning-dark); }
.row.fine .when { color: var(--text-secondary); }
:root[data-color-scheme="dark"] .row.soon .when { color: var(--chart-within30); }
@media (prefers-color-scheme: dark) {
  :root:not([data-color-scheme="light"]) .row.soon .when { color: var(--chart-within30); }
}

/* One coral dot on the rows already past their date. The only decoration on the board, and it marks the single
   state that costs somebody a morning. */
.row.gone .what::before {
  content: '';
  display: inline-block;
  width: 5px;
  height: 5px;
  margin-right: 0.5rem;
  vertical-align: middle;
  background: var(--chart-overdue);
  border-radius: 50%;
}

/* ── the secondary branch ─────────────────────────────────────────────────────────────────────────────────── */

.lines { display: grid; gap: 1.25rem 2rem; grid-template-columns: 1fr; margin-top: 2rem; }
@media (min-width: 52rem) { .lines { grid-template-columns: repeat(3, 1fr); } }
.lines li { display: grid; grid-template-columns: auto 1fr; gap: 0 0.75rem; align-items: start; }
.lines .icon { margin-top: 0.25rem; font-size: 1.0625rem; color: var(--primary-main); }
.lines b { font-size: var(--fs-h6); font-weight: 500; }
.lines span { grid-column: 2; font-size: var(--fs-body2); color: var(--text-secondary); }

/* ── where it came from ───────────────────────────────────────────────────────────────────────────────────
   FRAMELESS, though it was a panel until the sections were reordered (#197). It now sits directly above the
   closing call to action, which IS a framed panel, and two framed boxes in a row read as one long block — the
   call to action loses the emphasis it exists for. The change of voice is carried by the mark and the eyebrow,
   which is enough: this is the only place on the page where a logo other than the product's appears.

   Narrow measure, because it is prose rather than an interface. */
.origin { max-width: 46rem; }
.ec-logo { display: block; margin-bottom: 1.5rem; }
/* A HEIGHT AND NOTHING ELSE. The two files are not the same shape (800×168 and 900×190), so a shared width or a
   restated ratio would squash one of them by a percent or two — silently, which is the only way that defect ever
   arrives. */
.ec-logo img { display: block; width: auto; height: 30px; }

.origin .eyebrow { margin-bottom: 0.75rem; }
.origin h2 { font-size: var(--fs-h4); letter-spacing: -0.01em; }
.origin p + p { margin-top: 1rem; }
.origin p:not(.eyebrow) { color: var(--text-secondary); }
.origin h2 + p { margin-top: 1rem; }

/* ── roles ────────────────────────────────────────────────────────────────────────────────────────────────── */

/* TWO COLUMNS, NOT FOUR. Four put these entries at 29 characters a line — a newspaper column with none of a
   newspaper's reasons — and the last row is still full at two, so nothing is marooned. */
.roles { display: grid; gap: 1.5rem 2.5rem; grid-template-columns: 1fr; margin-top: 2rem; }
@media (min-width: 44rem) { .roles { grid-template-columns: repeat(2, 1fr); } }
.roles > div { padding-left: 1rem; border-left: 2px solid var(--primary-fill); }
.roles dt { font-size: var(--fs-h6); font-weight: 500; }
.roles dd { margin-top: 0.25rem; font-size: var(--fs-body2); color: var(--text-secondary); }

/* ── guards ───────────────────────────────────────────────────────────────────────────────────────────────── */

.guards { display: grid; gap: 1.5rem 2.5rem; grid-template-columns: 1fr; margin-top: 2rem; }
@media (min-width: 52rem) { .guards { grid-template-columns: repeat(2, 1fr); } }
.guards li { display: grid; grid-template-columns: auto 1fr; gap: 0 0.875rem; align-items: start; }
.guards .icon { margin-top: 0.2rem; font-size: 1.125rem; color: var(--success-main); }
.guards h3 { font-size: var(--fs-h6); }
.guards p { grid-column: 2; margin-top: 0.25rem; font-size: var(--fs-body2); color: var(--text-secondary); }

/* ── the tile field, and the demo ─────────────────────────────────────────────────────────────────────────────
   `sections/auth/AuthBackground.tsx`'s motif: not the mark, but the four-tile grid the mark is drawn on, scaled up
   and scattered. `01-logo.md` forbids the mark as a texture — no instance here reads as one. */
.tiles { position: absolute; inset: 0; z-index: -1; overflow: hidden; pointer-events: none; }
.tiles svg { width: 100%; height: 100%; }

.demo {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  margin-block: clamp(1.5rem, 4vw, 3rem);
  padding: clamp(2rem, 5vw, 3.5rem);
  background: var(--bg-paper);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
}
.demo-inner { max-width: 38rem; }
.demo h2 { font-size: var(--fs-h4); }
.demo p { margin-top: 0.75rem; color: var(--text-secondary); }
.demo .actions { justify-content: flex-start; margin-top: 1.5rem; }
.demo-host { font-size: var(--fs-body2); color: var(--text-secondary); }

/* ── footer ───────────────────────────────────────────────────────────────────────────────────────────────── */

.foot {
  padding-block: 2rem 2.5rem;
  font-size: var(--fs-caption);
  color: var(--text-secondary);
  border-top: 1px solid var(--divider);
}
.foot a { color: var(--link); text-decoration: none; }
.foot a:hover { text-decoration: underline; }
