/* Designed for a phone first. This guide is read on the employee's OLD phone,
   standing next to someone from IT, while they set up a new one — a desktop is
   the exception, not the target. So: fluid widths, tap targets no smaller than
   44px, inputs at 16px or larger so iOS does not zoom the page when one is
   focused, dvh rather than vh so browser chrome does not cut the footer off, and
   safe-area insets so the home indicator does not sit on top of a button.

   (The builder is desktop-only and styled separately in admin.css.)

   One palette, deliberately — no prefers-color-scheme switch.
   This page is shown to a new starter on their old phone with someone from IT
   beside them, and demonstrated to customers on whatever laptop is to hand. A
   design that changed with the viewer's OS setting meant nobody could say what
   it looked like without asking whose screen it was on.

   BRAND_COLOR sets the page; the card sits on black so it reads as a thing to
   fill in rather than part of the background.

   These are the values before anything is chosen in the builder. All of them are
   overwritten at load by palette.js, which derives the full set from whichever
   colours somebody set — so a colour is written here once, as a default, and
   never assumed anywhere below. In particular: NOTHING that sits on a surface
   may be a literal white or black. Set the background to white and every
   hardcoded #fff on it disappears, which is exactly the bug these tokens fix. */
:root {
  /* The browser's own widgets — number keypads, autofill, scrollbars — follow
     this rather than the tokens below. Declared light so they match the page on
     a phone set to dark mode. */
  color-scheme: light;

  --bg: #f4f5f7;
  --card: #ffffff;
  --raised: #f7f8f9;
  --field: #fbfbfc;
  --field-line: #d9dde3;
  --ink: #102542;
  /* Headings, and the strings worth reading exactly: the work email, the pass. */
  --head: #102542;
  /* Body copy inside a card — a step below the heading, above the muted grey. */
  --prose: #3d4c62;
  --muted: #69748a;
  --line: #e5e7eb;
  --accent: #376af2;
  /* The accent as text. A brand colour is picked to be recognisable, not
     legible, so words use this and shapes use the accent itself. */
  --accent-text: #376af2;
  --accent-fill: #eef3fe;
  --accent-edge: #c3d3fb;
  --accent-ink: #1c3f8f;
  --accent-ring: rgba(55, 106, 242, 0.35);
  --btn-bg: #376af2;
  --btn-ink: #ffffff;
  --error: #d33a34;
  --ok: #1a9d63;
  --ok-fill: #e7f5ee;
  /* Text directly on the page background, rather than on a card. Chosen against
     the background by contrast, not assumed to be white. */
  --on-bg: #102542;
  --on-bg-muted: rgba(16, 37, 66, 0.66);
  --on-bg-faint: rgba(16, 37, 66, 0.08);

  /* ── Shape ──
     Two radii, not five. Cards and the dialog use the large one; anything you
     press or type into uses the small one. A control with the same corner as
     the card it sits in stops reading as a separate object. */
  --radius: 14px;
  --radius-control: 10px;
  /* One hairline everywhere. Weight carries hierarchy here, not rule thickness:
     a page of 1px lines with a single blue button has one obvious next action. */
  --hairline: 1px solid var(--line);
  /* Barely there. On a light ground a heavy shadow reads as a dialog that has
     come loose; the card is separated by its border, and the shadow only stops
     white-on-white from being flat. */
  --lift: 0 1px 2px rgba(16, 37, 66, 0.04);
  --lift-dialog: 0 24px 60px rgba(16, 37, 66, 0.16);
}

* { box-sizing: border-box; }

/* Headings take their own colour so it can be set apart from body text. One
   rule, low specificity — the notice palettes below set their own h2 and must
   keep winning, since a coloured callout is a surface of its own. */
h1,
h2,
h3,
.resume-title,
.chapter-title,
.gate-title {
  color: var(--head);
}

/* The hidden attribute is implemented by the UA stylesheet as display: none, so
   ANY author rule that sets display beats it. Several elements here are both
   toggled with .hidden and given display: flex, which silently made them
   permanently visible. This is the standard baseline for that trap. */
[hidden] { display: none !important; }

/* A closed <dialog> is hidden by the UA stylesheet, and ANY author rule that
   sets display beats it — the same trap as [hidden] above, and it has now been
   sprung. .person-dialog sets display:flex so its head can stay put while its
   body scrolls, which made it permanently visible at the foot of every page:
   an empty white box with a Send SMS button in it, on screen since v1.64.0,
   because every test of it had it open.
   
   Stated once, for every dialog there is and every dialog there will be, rather
   than left to be remembered per dialog — three of the four did remember, which
   is exactly the hit rate that makes a baseline worth having. */
dialog:not([open]) { display: none !important; }


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

body {
  margin: 0;
  min-height: 100dvh;
  background: var(--bg);
  color: var(--ink);
  font: 16px/1.55 -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
}

.page {
  width: 100%;
  max-width: 620px;
  margin: 0 auto;
  padding: 28px 16px calc(40px + env(safe-area-inset-bottom));
}

/* ── Masthead ─────────────────────────────────────────────────────────────── */

/* A column, so the logo can be ordered above the name it belongs to without
   moving it in the markup — where the name has to come first, since it is what
   shows if the image never loads. flex-start rather than the default stretch:
   an img in a stretched column loses its aspect ratio. */
.masthead {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  margin-bottom: 26px;
}
/* On the sign-in screen the masthead is the company alone, so it can sit closer
   to the card it introduces without crowding a sentence. */
#gate .masthead { margin-bottom: 22px; }
/* The masthead carries the page now that the cards are quiet. Weight and size
   do the separating that a coloured band used to. */
.brand {
  font-size: 27px;
  font-weight: 700;
  letter-spacing: -0.5px;
  line-height: 1.15;
  color: var(--on-bg);
}
/* The masthead is the company and nothing else. The line that used to live
   here — "follow the guide below" — was an instruction wearing a strapline's
   clothes, and extra margin never fixed it: directly under a wordmark IS the
   strapline position. It now sits above the list it refers to, as .guide-lede. */

/* Sized and coloured as a caption, not as a heading: it explains the list and
   then gets out of the way. Margin above is generous and below is tight, so it
   belongs to the list rather than floating between two things. */
.guide-lede {
  margin: 4px 0 12px;
  color: var(--on-bg-muted);
  font-size: 15px;
  line-height: 1.5;
}

/* ── Home view ────────────────────────────────────────────────────────────── */
/* Ordered for a phone: what to do next, then where you are, then reference. The
   work email has to be here — a new starter does not know it — but it is not the
   task, so it does not get the top of the screen. */

.loading { color: var(--on-bg-muted); text-align: center; padding: 32px 0; }

/* ── Identity card ── */

.identity {
  background: var(--card);
  border: var(--hairline);
  border-radius: var(--radius);
  box-shadow: var(--lift);
  padding: 14px 16px 15px;
  margin-bottom: 12px;
}

.identity-top {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 7px;
}
.identity-label {
  flex: 1;
  min-width: 0;
  font-size: 11.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--muted);
}
.identity .ghost {
  flex: 0 0 auto;
  min-height: 36px;
  padding: 6px 11px;
  font-size: 13px;
}

/* The whole address, wrapping if it must. Truncating the one string somebody
   came here to read — and will be typing into other screens — makes showing it
   pointless, and these addresses are long: 37 characters is ordinary. */
.identity-email {
  display: block;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 15px;
  line-height: 1.35;
  color: var(--head);
  /* One tap selects the lot, which on a phone is the difference between typing
     it correctly and not. */
  user-select: all;
  /* break-word rather than anywhere, so the <wbr> hints the script inserts at
     the @ and the dots are preferred over breaking mid-word. anywhere would
     ignore them and split wherever the line happened to run out. */
  overflow-wrap: break-word;
  word-break: normal;
}

.identity-who {
  margin: 7px 0 0;
  font-size: 12.5px;
  color: var(--muted);
}

/* ── Resume card ── */

/* The one card that is not just a surface: it carries the next action, so it
   keeps a tinted edge where everything else uses the hairline. */
.resume {
  background: var(--card);
  border: 1px solid var(--accent-edge);
  border-radius: var(--radius);
  padding: 20px;
  margin-bottom: 14px;
  box-shadow: var(--lift);
}
.resume-label {
  display: block;
  font-size: 11.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--accent-text);
}
.resume-title { font-size: 19px; margin: 6px 0 2px; letter-spacing: -0.2px; }
.resume-where { margin: 0 0 14px; font-size: 13.5px; color: var(--muted); }
.resume-count { margin: 8px 0 0; font-size: 12.5px; color: var(--muted); }
.resume button { margin-top: 16px; }
.resume.is-complete { border-color: var(--line); }
.resume.is-complete .resume-label { color: var(--ok); }

.bar { height: 6px; border-radius: 999px; background: var(--line); overflow: hidden; }
.bar-fill {
  height: 100%;
  width: 0;
  border-radius: 999px;
  background: var(--accent);
  transition: width 0.3s ease;
}

/* ── Chapters, collapsed ── */

/* One card with rules between the rows, rather than a stack of separate cards.
   A gap says "these are unrelated things"; a rule says "these are the parts of
   one list", which is what a set of chapters is. */
.chapters {
  background: var(--card);
  border: var(--hairline);
  border-radius: var(--radius);
  box-shadow: var(--lift);
  overflow: hidden;
}

.chapter + .chapter { border-top: var(--hairline); }

/* An open chapter is a section of its own again, so it gets its rule back on
   both sides and the rows below do not look like its children. */
.chapter.is-open + .chapter { border-top: var(--hairline); }

/* The row is a container now, not a control: it holds the button that starts
   the chapter and the button that expands it. Padding moved onto those, so each
   one's hit area is the space it appears to occupy. */
.chapter-head {
  display: flex;
  align-items: stretch;
  width: 100%;
}

.chapter-open {
  display: flex;
  align-items: center;
  gap: 12px;
  flex: 1;
  min-width: 0;
  min-height: 64px;
  padding: 14px 8px 14px 16px;
  text-align: left;
  font: inherit;
  background: transparent;
  border: 0;
  color: var(--ink);
  cursor: pointer;
}
.chapter-open:hover { background: var(--raised); filter: none; }
.chapter-open:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

.chapter-mark {
  flex: none;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--raised);
  border: 1px solid var(--line);
  color: var(--muted);
  font-size: 13px;
  font-weight: 600;
}
.chapter.is-done .chapter-mark {
  background: var(--ok-fill);
  border-color: transparent;
  color: var(--ok);
}

.chapter-label { flex: 1; min-width: 0; }
.chapter-title {
  display: block;
  font-size: 15.5px;
  font-weight: 600;
  letter-spacing: -0.1px;
}
.chapter-summary {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  /* Two lines, then ellipsis — rather than one line cut mid-word, which is what
     a phone did to every summary and reads as a rendering fault. Still bounded,
     so three chapters cannot push the list off the screen. */
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  margin-top: 2px;
  font-size: 13px;
  font-weight: 400;
  line-height: 1.35;
  color: var(--muted);
}
.chapter.is-done .chapter-title { color: var(--muted); }

.chapter-count {
  flex: none;
  font-size: 12.5px;
  font-variant-numeric: tabular-nums;
  color: var(--muted);
}
/* Sized to be hit with a thumb rather than aimed at. 44px is the smallest
   target anyone should have to find on a phone, and this one sits next to
   another control that does something different — so it gets the full width
   and the full height of the row. */
.chevron {
  flex: none;
  display: grid;
  place-items: center;
  width: 48px;
  min-height: 64px;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: 17px;
  cursor: pointer;
}
.chevron:hover { background: var(--raised); color: var(--ink); }
.chevron:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.chevron > span { display: block; transition: transform 0.2s ease; }
.chapter.is-open .chevron > span { transform: rotate(90deg); }

/* A hairline between the two, so the row reads as two things to press rather
   than one wide one. Only on hover of either — at rest the row should still
   look like a row. */
.chapter-head:hover .chevron { border-left: var(--hairline); }

.chapter-body { padding: 0 14px 14px; }
.chapter-body .chapter-start { margin-top: 10px; }

@media (prefers-reduced-motion: reduce) {
  .chevron > span, .bar-fill { transition: none; }
}

.steplist {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 2px;
}
.steplink {
  width: 100%;
  text-align: left;
  display: flex;
  align-items: center;
  gap: 10px;
  /* 44px minimum. At 10px padding these were 40px tall and genuinely fiddly to
     hit on a phone, which matters because this list is how somebody returns to a
     step they got wrong. */
  min-height: 44px;
  padding: 11px 12px;
  font: inherit;
  font-size: 14.5px;
  color: var(--ink);
  background: transparent;
  border: 0;
  border-radius: var(--radius-control);
  cursor: pointer;
}
.steplink::before {
  content: "○";
  color: var(--muted);
  font-size: 13px;
}
.steplink.is-done::before { content: "✓"; color: var(--ok); }
.steplink.is-done { color: var(--muted); }
.steplink:hover { background: var(--raised); }
.steplink:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

.badge {
  margin-left: auto;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 2px 7px;
  border-radius: 999px;
  background: var(--ok-fill);
  color: var(--ok);
}

/* ── Buttons and inputs ───────────────────────────────────────────────────── */

button {
  font: inherit;
  font-weight: 600;
  padding: 13px 18px;
  min-height: 48px;
  width: 100%;
  /* Stops the grey flash on tap, which reads as a mis-tap on iOS. */
  -webkit-tap-highlight-color: transparent;
  border: 1px solid var(--btn-bg);
  border-radius: var(--radius-control);
  background: var(--btn-bg);
  color: var(--btn-ink);
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
/* A button ending a form needs air above it; a second button below the first
   needs less than the form needs from its last field. Without these, the input,
   "Log ind" and "Start forfra" stack edge to edge and read as one control. */
form > button,
.tap-stage > button:not(.ghost) {
  margin-top: 20px;
}
form > button + button,
.tap-stage > button + button {
  margin-top: 10px;
}

/* Darken on hover rather than brighten: on a light ground `brightness(1.06)`
   moves a solid blue toward the page and the button appears to recede. */
button:hover:not(:disabled) { filter: brightness(0.94); }
button:focus-visible { outline: 3px solid var(--accent-ring); outline-offset: 2px; }
/* Two reasons a button is disabled, and they mean opposite things. Waiting for
   the field to be filled in is "not yet"; waiting for a request is "working on
   it". The progress cursor was written for the second and, once fields started
   holding buttons back, was telling people something was happening when nothing
   was. */
button:disabled { opacity: 0.55; cursor: not-allowed; }
button:disabled.is-busy { cursor: progress; }

/* The quieter half of a pair. A white button with a hairline and the same dark
   text as the page — not grey text, which reads as disabled next to a solid
   blue one. */
button.secondary {
  background: var(--card);
  border-color: var(--field-line);
  color: var(--head);
  font-weight: 600;
}
button.secondary:hover:not(:disabled) {
  filter: none;
  background: var(--raised);
  border-color: var(--muted);
}

button.ghost {
  width: auto;
  padding: 8px 14px;
  min-height: 40px;
  font-size: 14px;
  background: var(--card);
  border-color: var(--field-line);
  color: var(--head);
}
button.ghost:hover:not(:disabled) { filter: none; background: var(--raised); }

button.icon {
  /* The close button. 34px was a desktop-mouse size. */
  width: 44px;
  height: 44px;
  padding: 0;
  border-radius: 8px;
  background: transparent;
  border-color: transparent;
  color: var(--muted);
  font-size: 15px;
}
button.icon:hover { background: var(--raised); color: var(--ink); filter: none; }

label { display: block; font-size: 14px; font-weight: 550; margin: 16px 0 6px; }

input {
  width: 100%;
  padding: 13px 13px;
  min-height: 48px;
  /* Must not go below 16px: iOS Safari zooms the whole page when a smaller input
     is focused, and the page never zooms back out on its own. */
  font: inherit;
  font-size: 16px;
  border: 1px solid var(--field-line);
  border-radius: var(--radius-control);
  background: var(--field);
  color: var(--ink);
}
input:focus-visible {
  outline: 3px solid var(--accent-ring);
  outline-offset: 1px;
  border-color: var(--accent);
}
#tap-code, #tap-last4 { letter-spacing: 0.4em; font-variant-numeric: tabular-nums; }

/* ── The guide dialog ─────────────────────────────────────────────────────── */

.guide {
  width: min(560px, calc(100vw - 24px));
  max-height: min(88dvh, 780px);
  padding: 0;
  border: var(--hairline);
  border-radius: 18px;
  box-shadow: var(--lift-dialog);
  background: var(--card);
  color: var(--ink);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

/* A dialog centred in a small screen wastes the screen and puts the footer
   buttons somewhere the thumb has to reach for, so on a phone it sits low.
   
   Low, but not welded to the edge. Full-bleed with the bottom corners squared
   off made the footer read as part of the browser chrome rather than as the
   bottom of a card — two buttons floating at the end of the screen with nothing
   holding them. A small inset all round keeps the thumb reach and gives it an
   edge again, with the backdrop visible past it so it reads as something on top
   of the guide. */
@media (max-width: 560px) {
  .guide {
    width: calc(100vw - 20px);
    max-width: calc(100vw - 20px);
    max-height: 88dvh;
    margin: 0;
    position: fixed;
    left: 10px;
    right: 10px;
    top: auto;
    bottom: calc(10px + env(safe-area-inset-bottom));
    border-radius: 18px;
  }

  /* The safe-area padding belonged to a footer sitting on the screen edge. The
     card now clears the home indicator itself, so doubling it would only add a
     band of empty white. */
  .guide-foot {
    padding-bottom: 16px;
  }
}
/* Lighter than it was. The home view stays legible behind the dialog, which is
   what makes the step feel like a layer on top of the guide rather than a
   different screen. */
.guide::backdrop { background: rgba(16, 37, 66, 0.42); backdrop-filter: blur(2px); }

/* No rule under it. The heading below is doing the separating, and a hairline
   plus a large bold title is one line too many.

   The close button comes out of the flow and pins to the corner. In a row it
   was a 44px element on one side and nothing on the other, so a "centred"
   heading beside it sat 22px off true — visible on any screen, and the kind of
   thing you can see is wrong without being able to say why. */
.guide-head {
  position: relative;
  padding: 16px 56px 4px;
  text-align: center;
}
.guide-head .icon {
  position: absolute;
  top: 8px;
  right: 8px;
}
.guide-where { min-width: 0; }
.guide-where span { display: block; }
.guide-where #chapter-name {
  font-size: 13px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--accent-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.guide-count { font-size: 13px; color: var(--muted); }

/* Centred, the whole column: heading, picture, and the sentence under it.
   A step is one instruction with one illustration, which is a poster rather than
   a document — and a centred column is what makes the picture and its caption
   read as one object instead of two stacked ones. */
.guide-body {
  padding: 8px 22px 26px;
  overflow-y: auto;
  /*
   * `flex: 1 1 auto`, never `flex: 1`.
   *
   * `flex: 1` means `1 1 0%` — a flex-basis of zero. This element is also a
   * scroll container, and a scroll container's automatic minimum size is zero
   * by spec rather than its content. Between the two, the body contributes
   * NOTHING to the height of a dialog that is sized by its content: the dialog
   * comes out as tall as its header and footer, and the body is given what is
   * left, which is nothing. A step with a title, two buttons and no text
   * between them.
   *
   * Chrome resolves the available space differently and filled it anyway, which
   * is why this only ever appeared on the phones. `auto` makes the basis the
   * content, so the dialog grows to fit up to its max-height and the body
   * scrolls past that.
   */
  flex: 1 1 auto;
  text-align: center;
}
.guide-body:focus-visible { outline: none; }
.guide-body h1 {
  font-size: 25px;
  line-height: 1.2;
  margin: 0 0 18px;
  letter-spacing: -0.4px;
  text-wrap: balance;
}

.prose p { margin: 0 0 12px; color: var(--prose); font-size: 15.5px; }
.prose p:last-child { margin-bottom: 0; }

/* ── Formatting an author can use ── */

/* A heading inside a step body. Smaller than the step's own title, because it
   is a subdivision of it and not a rival to it. */
.prose h2 {
  margin: 18px 0 8px;
  font-size: 17px;
  font-weight: 650;
  letter-spacing: -0.15px;
  color: var(--head);
}
.prose h2:first-child { margin-top: 0; }

.prose strong { font-weight: 650; color: var(--head); }
.prose em { font-style: italic; }
.prose u { text-underline-offset: 2px; }

/* Bullets, left-aligned inside a centred dialog: a ragged-left list is
   unreadable, and centring the markers as well would put them in the middle of
   the sentence. The list is centred as a block; its contents are not. */
.prose ul {
  margin: 0 0 12px;
  padding-left: 22px;
  text-align: left;
  display: inline-block;
  color: var(--prose);
  font-size: 15.5px;
}
.prose ul:last-child { margin-bottom: 0; }
.prose li { margin: 0 0 5px; }
.prose li:last-child { margin-bottom: 0; }
.prose li::marker { color: var(--accent); }

/* Centred text needs a shorter measure than left-aligned text: with both edges
   ragged, the eye has no fixed point to return to and a long line is genuinely
   slower to read. Narrow enough that a sentence is one or two lines, centred as
   a block so it stays under the heading rather than drifting left. */
.guide-body .prose,
.guide-body .lede,
.guide-body .hint,
.guide-body .warn {
  /* One measure for the column, not one per element.
     `ch` resolves against the element's OWN font-size, so 42ch was 423px on the
     body text, 410px on the lede and 357px on the hint — three different
     widths stacked and centred, which reads as text that will not line up.
     A rem is the same length everywhere, so the edges agree while the sizes
     still differ, which is the part that was meant to. */
  max-width: 26.5rem;
  margin-inline: auto;
}
/* Balanced rather than ragged: the last line of a centred paragraph left on its
   own reads as a mistake. */
.guide-body .prose p { text-wrap: pretty; }

.step-image,
.step-video {
  /* Up to the full width but never past its own size, and centred. A framed
     phone screenshot is usually narrower than the dialog, and stretching it to
     the edges is what made it look pasted in rather than placed. */
  /* width: 100% + height: auto, with the natural width as a ceiling.
     
     Both halves are load-bearing, and I got this wrong twice. height: auto is
     what lets the width/height attributes act as an aspect ratio rather than
     pinning the height to a pixel value and stretching the picture. And the
     width has to be *definite* — with width: auto the browser has no width to
     apply that ratio to before the file arrives, so nothing is reserved and the
     page still jumps.
     
     The ceiling keeps the earlier decision: a small screenshot is not blown up
     to the dialog's width. It is set inline per image, from the dimensions
     recorded at upload. */
  width: 100%;
  height: auto;
  max-width: 100%;
  margin: 0 auto 18px;
  border-radius: 12px;
  border: var(--hairline);
  display: block;
  /* No fill behind an image that is about to cover it. The panel was there to
     mark the space while loading, but with the box already reserved it only
     shows as a pale rectangle flashing once — which is the blink itself. */
  background: transparent;
}
.step-video { width: 100%; background: var(--raised); }
/* A framed phone screenshot is already a picture of a thing on a background;
   putting a border and a panel behind it boxes a box. Authors upload these as
   PNGs with transparency, so this lets them sit on the card. */
.step-image[src$=".png"] { border-color: transparent; }
.step-video { aspect-ratio: 16 / 9; height: auto; }

.guide-foot {
  display: flex;
  align-items: center;
  /* space-between, so that when the dots are hidden — a chapter long enough that
     they stop meaning anything — the two buttons still sit at the edges rather
     than bunching at the left. */
  justify-content: space-between;
  gap: 12px;
  padding: 16px 22px calc(18px + env(safe-area-inset-bottom));
  border-top: var(--hairline);
  /* The buttons stay put while the body scrolls: on a long step the thumb should
     not have to scroll to the end to find "Næste". */
  flex: none;
  background: var(--card);
}
/* Back left, forward right, position in the middle. The two buttons are not a
   pair of equals — one is the way on and one is the way back — so they are not
   given equal width either. */
.guide-foot button { width: auto; flex: 0 0 auto; min-width: 116px; }

/* Which step this is, as shape rather than as a sentence. The current one is a
   pill rather than a bigger dot: length reads as "you are here" at a glance,
   where a larger circle just looks like a rendering artefact. */
.dots {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-width: 0;
  /* Many steps on a narrow phone would push the buttons out; the row scrolls
     rather than the footer growing. */
  overflow: hidden;
}
.dot {
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 999px;
  background: var(--line);
  transition: width 0.2s ease, background-color 0.2s ease;
}
/* Steps already done, so the row shows progress and not only position. */
.dot.is-done { background: var(--accent-edge); }
.dot.is-current { width: 26px; background: var(--accent); }

@media (max-width: 420px) {
  .guide-foot button { min-width: 92px; padding: 13px 12px; }
  /* Nine dots at 8px with 7px gaps is 128px, and a 360px screen leaves the row
     about 100px once the two buttons have taken theirs. Smaller and tighter
     rather than clipped: a cut-off row of dots reads as a rendering fault. */
  .dots { gap: 4px; }
  .dot { width: 6px; height: 6px; }
  .dot.is-current { width: 20px; }
}

/* ── The credential step ──────────────────────────────────────────────────── */

.tap { margin-top: 4px; }
/* auto, not 0 — a plain `margin: 0 0 4px` cancels the margin-inline: auto that
   centres every other paragraph in this column, so this one sat against the
   left edge while the rest were centred. */
.tap .lede { margin: 0 auto 4px; color: var(--prose); font-size: 15.5px; }

/* Every line in a stage shares the column's measure. Capping only .lede, .hint
   and .warn left the plain paragraphs uncapped and half a centimetre wider than
   the text above them. */
.tap-stage p {
  max-width: 26.5rem;
  margin-inline: auto;
  /* And the same size and colour as the lede above it. Inheriting left the
     second line of a confirmation larger and darker than the first, which puts
     the emphasis on the follow-up rather than on the news. */
  font-size: 15.5px;
  color: var(--prose);
}
.hint { font-size: 13.5px; color: var(--muted); margin: 14px 0 0; }

.warn {
  font-size: 13.5px;
  margin: 12px 0 0;
  padding: 11px 13px;
  border-radius: var(--radius-control);
  background: #fff8ec;
  border: 1px solid #f0e0c2;
  color: #6f4710;
}

.error {
  margin: 14px 0 0;
  padding: 11px 13px;
  border-radius: var(--radius-control);
  background: #fdf1f0;
  border: 1px solid #f4d3d0;
  color: #8a231e;
  font-size: 14.5px;
}

.passbox {
  margin-top: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  /* Wraps rather than squeezing: an eight-digit pass at 25px plus a button does
     not fit across a 390px screen, and a squeezed passcode is one that gets
     mistyped. */
  flex-wrap: wrap;
  /* Tight. The code and its button used to take a row each — the code was
     flex-basis 100% — which made a panel three times taller than the eight
     characters inside it. They sit on one line now and only wrap when a long
     passcode genuinely needs the width. */
  padding: 12px 14px;
  gap: 10px;
  border-radius: 12px;
  background: var(--accent-fill);
  border: 1px solid var(--accent-edge);
}
.pass {
  /* Grows to what it needs and wraps only if it must, rather than always
     claiming a whole row. */
  flex: 1 1 auto;
  min-width: 0;
  text-align: center;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: clamp(20px, 6vw, 24px);
  letter-spacing: 0.14em;
  color: var(--head);
  /* The one string on this page worth being able to select cleanly — and on a
     phone, tapping once to select all of it is the difference between typing it
     correctly and not. Entra generates a mixed-case alphanumeric passcode with
     symbols (verified against a real tenant, e.g. "kP7mQ2x#"), so retyping it by
     hand on a phone keyboard is genuinely error-prone. */
  user-select: all;
  overflow-wrap: anywhere;
}
.passbox .ghost { flex: 0 0 auto; min-height: 40px; padding: 7px 14px; }
/* The masked state is dots, not a passcode: it does not need the tracking that
   makes a real one readable, and at 0.22em eight dots were as wide as the box. */
.pass.masked { color: var(--muted); letter-spacing: 0.12em; user-select: none; }

.check {
  margin-inline: auto;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--ok-fill);
  color: var(--ok);
  font-size: 23px;
  margin-bottom: 14px;
}

.watching {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
  font-size: 13.5px;
  color: var(--muted);
}
.spinner {
  flex: none;
  width: 13px;
  height: 13px;
  border: 2px solid var(--line);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* Someone waiting on a credential should not be handed a strobing element. */
@media (prefers-reduced-motion: reduce) {
  .spinner { animation-duration: 3s; }
  .progress-bar { transition: none; }
}

/* ── Footer ───────────────────────────────────────────────────────────────── */

.support {
  margin: 30px 0 0;
  text-align: center;
  font-size: 13.5px;
  color: var(--on-bg-muted);
}
.support a { color: var(--on-bg); }

@media (max-width: 480px) {
  .page { padding: 20px 12px calc(32px + env(safe-area-inset-bottom)); }
  .masthead { margin-bottom: 18px; }
  .chapter-open { padding: 11px 6px 11px 12px; gap: 10px; }
  .chevron { width: 44px; }
  .chapter-title { font-size: 15px; }
  .chapter-body { padding: 0 12px 12px; }
  .resume { padding: 16px; }
  .resume-title { font-size: 17.5px; }
  .guide-body { padding: 18px 16px 22px; }
  .guide-foot { padding: 12px 16px calc(14px + env(safe-area-inset-bottom)); }
  .guide-body h1 { font-size: 19.5px; }
  .identity { padding: 11px 12px 12px; }
  .identity-email { font-size: 14px; }

  /* Tilbage/Næste side by side get cramped; Næste is the common action, so it
     keeps the width and Tilbage shrinks to what it needs. */
  .guide-foot .secondary { min-width: 92px; }
}

/* ── Sign-in gate ─────────────────────────────────────────────────────────── */

.gate-title { font-size: 21px; margin: 0 0 6px; letter-spacing: -0.3px; }
/* What this page wants, said where the form is rather than under the logo. */
.gate-lede { margin: 0 0 20px; color: var(--muted); font-size: 14.5px; }
/* The sign-in panel reuses .chapter, which stopped carrying its own background
   when chapters became rows inside one card — inside .chapters they inherit the
   container's white, but this one stands alone. It had been transparent since,
   showing the page colour through a card whose text was chosen for white. */
#gate .chapter {
  background: var(--card);
  padding: 24px 22px 26px;
  border: var(--hairline);
  border-radius: var(--radius);
  box-shadow: var(--lift);
}
#gate label:first-of-type { margin-top: 0; }
#signin-last4, #signin-otp { letter-spacing: 0.4em; font-variant-numeric: tabular-nums; }

button.linkish {
  flex: 0 0 auto;
  width: auto;
  padding: 4px 2px;
  min-height: 36px;
  background: none;
  border: 0;
  color: var(--accent-text);
  font-weight: 500;
  font-size: 13px;
  text-decoration: underline;
}
button.linkish:hover { filter: none; color: var(--head); }

/* Values that came from the reader's own account, marked so it is obvious which
   words are theirs and which are the guide's. It matters most on the email
   address: that is the string they will be typing into other screens, and it
   should be findable at a glance rather than read out of a sentence. */
.var {
  display: inline-block;
  padding: 1px 6px;
  margin: 0 1px;
  border-radius: 5px;
  background: var(--accent-fill);
  border: 1px solid var(--accent-edge);
  color: var(--accent-ink);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.94em;
  /* Long addresses must be selectable in one go, and must not push the dialog
     sideways on a narrow phone. */
  user-select: all;
  overflow-wrap: anywhere;
}

/* In a heading it is a name, not a value to copy — same family, less box. */
h1 .var {
  background: transparent;
  border-color: transparent;
  padding: 0;
  font-family: inherit;
  font-size: inherit;
  color: var(--accent-text);
}

/* Shown only when SMS_PROVIDER is one that sends nothing — see the comment on
   /api/dev/last-code. Styled to look like scaffolding rather than part of the
   product, so nobody mistakes it for a feature or misses that it is on. */
.devbox {
  margin-top: 18px;
  padding: 12px 14px;
  border-radius: var(--radius-control);
  background: #fff8ec;
  border: 1px dashed #d69528;
  color: #6f4710;
  font-size: 13.5px;
}
.devbox strong {
  display: block;
  margin-top: 6px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 26px;
  letter-spacing: 0.22em;
  color: #ffd98a;
  user-select: all;
}
.devbox .devbox-note { display: block; margin-top: 6px; opacity: 0.8; font-size: 12.5px; }

/* ── Practical information ────────────────────────────────────────────────── */
/* Not a step and not styled like one: no number, no progress, nothing to tick
   off. Amber rather than green so it reads as "note this" rather than "do this",
   and above the guide because it is the part that is true only today. */

.notices { display: grid; gap: 10px; margin-bottom: 12px; }

.notice {
  background: #fff8ec;
  border: 1px solid #f0e0c2;
  border-left: 3px solid #d69528;
  border-radius: var(--radius);
  padding: 14px 16px;
}
.notice h2 {
  margin: 0 0 6px;
  font-size: 15.5px;
  letter-spacing: -0.1px;
  color: #6f4710;
}
.notice .prose p {
  margin: 0 0 8px;
  font-size: 14.5px;
  color: #5d4a2c;
}
.notice .prose p:last-child { margin-bottom: 0; }

/* A variable inside a notice keeps the marking, but tinted to its surroundings
   rather than carrying the guide's green into an amber card. */
.notice .var {
  background: #fbeed6;
  border-color: #e6cf9f;
  color: #66450f;
}

.notice-image {
  width: 100%;
  border-radius: 10px;
  border: 1px solid #f0e0c2;
  margin: 4px 0 10px;
  display: block;
}

/* ── Notice colours ──────────────────────────────────────────────────────── */
/* Roles, not decoration. Amber for everything trains people to ignore the
   colour, which is the one job a colour has.

   Each scheme sets its own background, rule, heading and body together, so a
   callout stays internally consistent whatever the card behind it is doing.
   They are tints of white rather than blocks of colour: on a light page a
   saturated panel shouts over the step it is annotating. */

.notice-amber { background: #fff8ec; border-color: #f0e0c2; border-left-color: #d69528; }
.notice-amber h2 { color: #6f4710; }
.notice-amber .prose p { color: #5d4a2c; }
.notice-amber .var { background: #fbeed6; border-color: #e6cf9f; color: #66450f; }

.notice-green { background: #eef8f2; border-color: #cbe6d7; border-left-color: #1a9d63; }
.notice-green h2 { color: #0e5334; }
.notice-green .prose p { color: #32513f; }
.notice-green .var { background: #dcefe4; border-color: #b0d9c3; color: #12583a; }

.notice-blue { background: #eff4fe; border-color: #cfdcfa; border-left-color: #376af2; }
.notice-blue h2 { color: #1a3a80; }
.notice-blue .prose p { color: #384866; }
.notice-blue .var { background: #e1eafd; border-color: #bdd0f8; color: #1f4189; }

.notice-red { background: #fdf1f0; border-color: #f4d3d0; border-left-color: #d33a34; }
.notice-red h2 { color: #8a231e; }
.notice-red .prose p { color: #66403d; }
.notice-red .var { background: #fae0de; border-color: #eebfbb; color: #8d2823; }

.notice-grey { background: #f5f6f8; border-color: #e1e4e9; border-left-color: #78839a; }
.notice-grey h2 { color: #2a3547; }
.notice-grey .prose p { color: #47536a; }
.notice-grey .var { background: #eaedf1; border-color: #d3d8df; color: #313d51; }

/* ── Reference chapters ──────────────────────────────────────────────────── */
/* Browsable, not completable: no number, no progress, no ticks. Otherwise "how
   the alarm works" becomes an unfinished task, and the guide never ends. */

.chapter.is-reference .chapter-mark {
  background: transparent;
  border-color: var(--line);
  color: var(--muted);
  font-style: italic;
  font-family: Georgia, serif;
}
.chapter.is-reference .chapter-count { font-variant-numeric: normal; }

/* No circle-or-tick bullet: there is nothing to complete. */
.steplink.is-plain::before { content: "–"; color: var(--muted); }
.steplink.is-plain { color: var(--ink); }

/* Media order inside a step is set per step, so the body has to be a flex column
   for `order` to mean anything. */
.guide-body { display: flex; flex-direction: column; }
.guide-body h1 { order: -1; }

/* A scrolling flex column shrinks its children before it agrees to scroll, and
   Safari does so more eagerly than the others — which squashes a paragraph
   instead of letting the container scroll past it. Nothing here should ever be
   compressed to fit; the container has overflow for that. */
.guide-body > * { flex-shrink: 0; }

/* The logo — uploaded in the builder, or the tenant's own. Bounded in both
   directions: these arrive at whatever size somebody happened to export, and on
   a phone the masthead sits directly above the one thing the reader came to do.
   The height is a setting; the width still cannot exceed the screen. */
.brand-logo {
  display: block;
  order: -1;
  max-width: min(220px, 60vw);
  max-height: var(--logo-height, 40px);
  width: auto;
  height: auto;
  object-fit: contain;
  object-position: left center;
}

/* Shown under the mark rather than instead of it. Smaller than a standalone
   wordmark: here the logo is the title and the name is the caption. */
.brand.under-logo {
  margin-top: 9px;
  font-size: 16px;
}

/* Country code as an affix, not as text in the value. Inside the input it got
   re-parsed on every keystroke; see applyPhoneHint in guide.js. */
.tel-field {
  display: flex;
  align-items: stretch;
  gap: 0;
  /* The ring goes on the pair, not on the input.
     +45 and the number are two elements pretending to be one control, so an
     outline around the input alone traces a shape with square left corners and
     draws a line straight down the middle of the control — and outline-offset
     then floats that line over the prefix. Ringing the group is the only
     version whose shape matches what the eye reads as the field. */
  border-radius: var(--radius-control);
}
.tel-field:focus-within {
  outline: 3px solid var(--accent-ring);
  outline-offset: 1px;
}
/* Both halves take the focus colour, so the join does not stay grey down the
   middle of a focused control. */
.tel-field:focus-within .tel-prefix,
.tel-field:focus-within input { border-color: var(--accent); }
/* Suppressed only inside the group — a bare input keeps its own ring. */
.tel-field input:focus-visible { outline: none; }
.tel-prefix {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  padding: 0 12px;
  min-height: 48px;
  border: 1px solid var(--field-line);
  border-right: 0;
  border-radius: var(--radius-control) 0 0 var(--radius-control);
  background: var(--field);
  color: var(--muted);
  font-size: 16px;
  font-variant-numeric: tabular-nums;
  user-select: none;
}
.tel-field input {
  flex: 1;
  min-width: 0;
  border-radius: 0 var(--radius-control) var(--radius-control) 0;
  letter-spacing: 0.12em;
  font-variant-numeric: tabular-nums;
}
.tel-prefix[hidden] + input { border-radius: var(--radius-control); }

/* The running version. Small, always present — "did my change deploy" should be
   answerable by looking at the page, not by comparing file sizes. */
.version {
  display: inline-block;
  margin-left: 8px;
  padding: 1px 6px;
  border-radius: 999px;
  background: var(--on-bg-faint);
  color: var(--on-bg-muted);
  font-size: 11.5px;
  font-variant-numeric: tabular-nums;
}

/* ── Background image ─────────────────────────────────────────────────────── */
/* Set from settings. The colour stays underneath: it is what shows while the
   image loads, and on a connection where it never arrives — which on mobile data
   is an outcome, not a hypothetical.

   Which image is used is a media query rather than a measurement in JavaScript,
   so rotating a phone picks the right one with nothing running again. */

:root {
  --bg-image-mobile: none;
  --bg-image-desktop: none;
  --bg-overlay: 0;
}

body {
  background-image: var(--bg-image-mobile);
  background-size: cover;
  background-position: center center;
  /* Fixed so the image does not crawl as the page scrolls. Deliberately not on
     iOS, where fixed attachment is unreliable and produces visible jumping. */
  background-attachment: scroll;
  background-repeat: no-repeat;
}

@media (min-width: 700px) {
  body {
    background-image: var(--bg-image-desktop);
    background-attachment: fixed;
  }
}

/* The scrim. Every text colour here was chosen against a dark background, so a
   bright photograph without this makes the masthead unreadable. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, var(--bg-overlay));
  pointer-events: none;
  z-index: 0;
}

/* Content above the scrim. */
.page { position: relative; z-index: 1; }
.guide { z-index: 2; }

/* ── Confirming Authenticator ─────────────────────────────────────────────── */
/* One button and three possible answers. Deliberately plain: the reader has just
   done a long piece of setup elsewhere, and this screen exists only to ask
   whether it worked. */

.verify { margin-top: 4px; }
.verify-stage > button { margin-top: 4px; }
.verify .warn { text-align: left; }

/* A pass shown on a step that is not the pass step. Same box, less ceremony —
   it is a reference here, not the event. */
.tap-inline { margin-top: 14px; }
.tap-inline .passbox { margin-top: 0; }
.tap-inline .hint { margin-top: 0; }
/* The offer to fetch one, when there is none to show. Narrower than a full-width
   action: it is a way out of a dead end, not the step's own purpose. */
.tap-inline [data-none] button {
  width: auto;
  min-width: 200px;
  margin-top: 10px;
  /* A label broken across two lines turns a button into a paragraph with a
     border. The step's own text has already said "midlertidig adgangskode", so
     the short form reads fine here. */
  white-space: nowrap;
}

/* Quiet, and below everything it affects. Destructive and rarely wanted, so it
   should be findable rather than prominent. */
.reset-row { margin: 18px 0 0; text-align: center; }
.reset-row .linkish { color: var(--on-bg-muted); }
.reset-row .linkish:hover { color: var(--on-bg); }

/* ── Asking ───────────────────────────────────────────────────────────────── */
/* The same card as the step dialog, smaller. Not a native confirm(): that puts
   the hostname above the question, which on the screen where somebody is about
   to be handed a credential reads as the browser interrupting rather than the
   page asking. */

.confirm {
  width: min(400px, calc(100vw - 32px));
  padding: 24px 22px 20px;
  border: var(--hairline);
  border-radius: 18px;
  box-shadow: var(--lift-dialog);
  background: var(--card);
  color: var(--ink);
  text-align: center;
}
.confirm::backdrop { background: rgba(16, 37, 66, 0.42); backdrop-filter: blur(2px); }

.confirm h2 { margin: 0 0 8px; font-size: 19px; letter-spacing: -0.2px; }
.confirm p { margin: 0 0 20px; color: var(--prose); font-size: 15px; }

.confirm-foot { display: flex; gap: 10px; }
.confirm-foot button { flex: 1; }

/* One button when there is nothing to decide — just something to be told. */
.confirm.is-message .confirm-foot button.secondary { display: none; }

/* Under the chapter's own button, quieter than it: undoing work is not the
   thing somebody came to this row to do. */
.chapter-reset {
  display: block;
  margin: 10px auto 2px;
  font-size: 12.5px;
  color: var(--muted);
}
.chapter-reset:hover { color: var(--head); }

/* ── Finishing a chapter ──────────────────────────────────────────────────── */
/* Motion is spent here and almost nowhere else. Everything in this guide is
   something somebody has to do; this is the one screen that only tells them they
   have done it, and it should feel like that. */

.celebrate {
  position: relative;
  overflow: hidden;
  width: min(360px, calc(100vw - 32px));
  padding: 28px 24px 22px;
  border: var(--hairline);
  border-radius: 18px;
  box-shadow: var(--lift-dialog);
  background: var(--card);
  color: var(--ink);
  text-align: center;
}
.celebrate::backdrop { background: rgba(16, 37, 66, 0.42); backdrop-filter: blur(2px); }
.celebrate[open] { animation: celebrate-in 0.28s cubic-bezier(0.2, 0.9, 0.3, 1.3) both; }

@keyframes celebrate-in {
  from { opacity: 0; transform: scale(0.94) translateY(8px); }
  to { opacity: 1; transform: none; }
}

.celebrate h2 { margin: 14px 0 6px; font-size: 20px; letter-spacing: -0.2px; }
.celebrate p { margin: 0 0 20px; color: var(--prose); font-size: 15px; }
.celebrate button { width: 100%; }

/* The tick draws itself, after its ring. A mark that appears was always there;
   one that is drawn just happened, which is the whole message. */
.celebrate-tick { width: 58px; height: 58px; display: block; margin: 0 auto; }
.celebrate-tick circle {
  fill: none;
  stroke: var(--accent-edge);
  stroke-width: 3;
  stroke-dasharray: 152;
  stroke-dashoffset: 152;
  animation: ring-draw 0.45s ease-out forwards;
}
.celebrate-tick path {
  fill: none;
  stroke: var(--accent);
  stroke-width: 4;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 44;
  stroke-dashoffset: 44;
  animation: tick-draw 0.32s ease-out 0.34s forwards;
}

@keyframes ring-draw { to { stroke-dashoffset: 0; } }
@keyframes tick-draw { to { stroke-dashoffset: 0; } }

/* Confetti, as a dozen spans rather than a canvas: it runs on the compositor,
   costs nothing on an old phone, and cannot outlive the dialog that owns it. */
/* Clipped here rather than by the dialog. The pieces start above the top edge
   so they fall into view, and leaving that to the dialog's own overflow let nine
   of fourteen paint outside the card onto the backdrop. Its own layer, its own
   clip, and the radius inherited so the corners match. */
.confetti {
  position: absolute;
  inset: 0;
  overflow: hidden;
  border-radius: inherit;
  pointer-events: none;
}
.confetti span {
  position: absolute;
  top: -12px;
  width: 7px;
  height: 11px;
  border-radius: 1px;
  opacity: 0;
  animation: fall 1.5s ease-in forwards;
}

@keyframes fall {
  0% { opacity: 0; transform: translateY(-10px) rotate(0deg); }
  10% { opacity: 1; }
  100% { opacity: 0; transform: translateY(320px) rotate(540deg); }
}

/* Reduced motion still gets the news, just not the movement. */
@media (prefers-reduced-motion: reduce) {
  .celebrate[open] { animation: none; }
  .celebrate-tick circle,
  .celebrate-tick path { animation: none; stroke-dashoffset: 0; }
  .confetti { display: none; }
}

/* ── A question ───────────────────────────────────────────────────────────── */
/* The answers are the step's content, not a footer control, so they are full
   width and stacked — on a phone two options side by side is two cramped
   labels. */

.choice { margin-top: 6px; }
.choice-options { display: grid; gap: 10px; }

/* Equal answers get equal weight. Rendered as the quiet button rather than the
   blue one: blue means "this is the way on", and with two of them side by side
   it means it twice, which reads as a default nobody chose. */
.choice-option {
  width: 100%;
  background: var(--card);
  border-color: var(--field-line);
  color: var(--head);
}
.choice-option:hover:not(:disabled) {
  filter: none;
  background: var(--accent-fill);
  border-color: var(--accent-edge);
  color: var(--accent-ink);
}

.choice-chosen {
  margin: 4px 0 0;
  font-size: 14.5px;
  color: var(--muted);
}
.choice-chosen strong { color: var(--head); }
.choice-chosen .linkish { margin-left: 6px; }

/* A link inside a step's text. Underlined rather than only coloured: on a
   customer-chosen accent the colour alone can land anywhere from obvious to
   invisible, and the underline holds regardless of the palette. */
.guide-body a,
.notice a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-thickness: 1px;
  /* A pasted address can be longer than the dialog is wide. */
  overflow-wrap: anywhere;
}

.guide-body a:hover,
.notice a:hover { text-decoration-thickness: 2px; }

/* ── Locked, and what would open it ────────────────────────────────────────
   
   A chapter waiting on another one, and a step further ahead than the reader
   has got. Both are the author's decision and both are ordinary states rather
   than errors — nobody has done anything wrong by arriving early — so neither
   is drawn in the colour reserved for things that went wrong. */

/* Deliberately close to an ordinary pending chapter.
   
   The first version faded the title, the summary and the number all at once,
   and the row read as broken rather than as waiting — a chapter greyed out to
   the point of looking like a rendering fault, when the only thing wrong with
   it is that its turn has not come. Nothing here is disabled content; it is
   content whose turn is later.
   
   So the title keeps its colour and the number keeps its weight. The dashed
   ring is the whole visual difference, and the sentence underneath does the
   actual telling. */
.chapter.is-locked .chapter-mark {
  border-style: dashed;
  border-color: var(--field-line);
}

/* Where the summary would be. On a locked row the useful sentence is not what
   the chapter is about — it is what has to happen before it can be read. */
.chapter-gate {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 4px;
  font-size: 12.5px;
  font-weight: 600;
  line-height: 1.35;
  /* Body copy, not the muted grey the summary above it uses. This is the one
     line on the row that is doing any work — everything else is the chapter's
     own name — and it was set fainter than the sentence it had to beat. */
  color: var(--prose);
}
.chapter-gate-icon { font-size: 11px; }

/* Not a control. The row is a statement — this is chapter three, and here is
   what has to happen first — so it drops the hover and the pointer that
   promised it would do something when pressed. */
.chapter.is-locked .chapter-open {
  cursor: default;
  /* The UA fades a disabled button, and the row is already muted by design;
     two fades stack into something that reads as broken rather than as
     waiting. */
  opacity: 1;
}
.chapter.is-locked .chapter-open:hover { background: transparent; }

.steplink.is-blocked {
  color: var(--muted);
  cursor: not-allowed;
}
/* The open circle becomes a closed one. A step out of reach is not a step you
   have not done yet — it is one you cannot get to — and the marker is where the
   eye already is. */
/* --on-bg-faint is 8% ink, chosen for hairlines on the page background; on a
   white card it is invisible, and the row came out with no marker at all while
   every row above it had one. */
.steplink.is-blocked::before { content: "●"; color: var(--field-line); }
.steplink.is-blocked:hover { background: transparent; }
.steplink-lock { margin-left: auto; font-size: 11px; opacity: 0.5; }
/* A badge already claims margin-left:auto, so on a pass step the padlock would
   sit against it rather than at the end. */
.steplink .badge + .steplink-lock { margin-left: 8px; }

.chapter-start:disabled {
  opacity: 1;
  color: var(--muted);
  border-style: dashed;
  cursor: not-allowed;
}

/* ── Little interruptions ──────────────────────────────────────────────────
   
   A card thrown up now and again with the reader's own name on it. It has to be
   noticeable enough to break a skim and quiet enough that nobody resents it —
   so it dims the page rather than blocking it, and it leaves on its own. */

.splash {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: grid;
  place-items: center;
  padding: 24px;
  background: rgba(16, 37, 66, 0.42);
  /* Backdrop-filter is progressive: where it is unsupported the flat wash above
     still does the job. */
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  animation: splash-veil 220ms ease both;
}
.splash.is-leaving { animation: splash-veil 200ms ease both reverse; }

@keyframes splash-veil { from { opacity: 0 } to { opacity: 1 } }

.splash-card {
  max-width: 22rem;
  width: 100%;
  padding: 26px 24px 20px;
  border-radius: var(--radius);
  background: var(--card);
  box-shadow: 0 20px 60px -20px rgba(16, 37, 66, 0.45);
  text-align: center;
}

.splash-text {
  margin: 0 0 18px;
  font-size: 16.5px;
  line-height: 1.45;
  color: var(--head);
  text-wrap: balance;
}
/* The reader's own values, marked the way the guide marks them everywhere else
   — so their name reads as their name and not as a word somebody typed. The
   class is .var, which is what appendPiece actually sets. */
.splash-text .var { font-weight: 600; }

.splash-ok {
  width: 100%;
  min-height: 44px;
  font: inherit;
  font-weight: 600;
  color: var(--btn-ink);
  background: var(--btn-bg);
  border: 0;
  border-radius: var(--radius-control);
  cursor: pointer;
}
.splash-ok:focus-visible { outline: 3px solid var(--accent-ring); outline-offset: 2px; }

/* ── The animations ────────────────────────────────────────────────────────
   Six, each recognisably a different thing rather than six speeds of fade. */

.splash-pop     { animation: splash-pop 320ms cubic-bezier(0.34, 1.56, 0.64, 1) both; }
.splash-slide   { animation: splash-slide 300ms cubic-bezier(0.22, 1, 0.36, 1) both; }
.splash-fade    { animation: splash-fade 420ms ease both; }
.splash-bounce  { animation: splash-bounce 620ms cubic-bezier(0.28, 0.84, 0.42, 1) both; }
.splash-wiggle  { animation: splash-wiggle 600ms ease both; }
.splash-confetti { animation: splash-pop 320ms cubic-bezier(0.34, 1.56, 0.64, 1) both; }

@keyframes splash-pop {
  from { opacity: 0; transform: scale(0.86) }
  to   { opacity: 1; transform: scale(1) }
}
@keyframes splash-slide {
  from { opacity: 0; transform: translateY(38px) }
  to   { opacity: 1; transform: translateY(0) }
}
@keyframes splash-fade { from { opacity: 0 } to { opacity: 1 } }
@keyframes splash-bounce {
  0%   { opacity: 0; transform: translateY(-90px) }
  55%  { opacity: 1; transform: translateY(10px) }
  75%  { transform: translateY(-6px) }
  100% { transform: translateY(0) }
}
@keyframes splash-wiggle {
  0%   { opacity: 0; transform: scale(0.92) rotate(0deg) }
  40%  { opacity: 1; transform: scale(1) rotate(-2.4deg) }
  60%  { transform: rotate(2deg) }
  80%  { transform: rotate(-1deg) }
  100% { transform: rotate(0deg) }
}

/* Somebody who has asked their operating system for less movement has asked for
   it here too. The card still arrives — it is the message that matters, not the
   entrance. */
@media (prefers-reduced-motion: reduce) {
  .splash,
  .splash.is-leaving,
  .splash-card { animation-duration: 1ms !important; animation-iteration-count: 1 !important; }
}

/* ── Ofte stillede spørgsmål ───────────────────────────────────────────────
   
   Below the guide, because the guide is what somebody came for. These are the
   questions that otherwise arrive one at a time by telephone on the morning
   fifty people start — so they are laid out to be scanned for one's own
   question, not read through. */

.faq { margin-top: 26px; }

.faq-heading {
  margin: 0 0 10px;
  padding-left: 2px;
  font-size: 13px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--on-bg-muted);
}

.faq-item {
  background: var(--card);
  border-radius: var(--radius);
  overflow: hidden;
}
.faq-item + .faq-item { margin-top: 8px; }

.faq-question {
  display: flex;
  align-items: center;
  gap: 12px;
  /* 44px minimum, like every other target in this guide — read on a phone. */
  min-height: 48px;
  padding: 13px 16px;
  font-size: 14.5px;
  font-weight: 600;
  color: var(--head);
  cursor: pointer;
  /* Safari draws its own disclosure triangle and ignores list-style on the
     summary itself; both of these are needed to be rid of it, and the caret
     below is the one that follows this design. */
  list-style: none;
}
.faq-question::-webkit-details-marker { display: none; }
.faq-question:hover { background: var(--raised); }
.faq-question:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }

.faq-caret {
  margin-left: auto;
  flex: none;
  color: var(--muted);
  font-size: 18px;
  line-height: 1;
  transition: transform 0.18s ease;
}
.faq-item[open] > .faq-question > .faq-caret { transform: rotate(90deg); }

/* A rule between the question and its answer, drawn only while the answer is
   showing. Without it the two ran together as one block of text on one white
   card, and the only thing telling a reader where the question stopped was that
   it happened to be bold. */
.faq-item[open] > .faq-question { border-bottom: 1px solid var(--line); }

.faq-answer {
  /* Matches the question's own padding, so the answer starts as far below the
     rule as the question sits above it. */
  padding: 13px 16px 15px;
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--prose);
}
.faq-answer > *:first-child { margin-top: 0; }
.faq-answer > *:last-child { margin-bottom: 0; }

@media (prefers-reduced-motion: reduce) {
  .faq-caret { transition: none; }
}
