/* Self-hosted fonts (latin subset) served from /public/fonts. */
@font-face {
  font-family: "Bricolage Grotesque"; font-style: normal; font-weight: 500 800;
  font-display: swap; src: url("/fonts/bricolage-grotesque-latin.woff2") format("woff2");
}
@font-face {
  font-family: "Inter"; font-style: normal; font-weight: 400 700;
  font-display: swap; src: url("/fonts/inter-latin.woff2") format("woff2");
}
@font-face {
  font-family: "DM Mono"; font-style: normal; font-weight: 400;
  font-display: swap; src: url("/fonts/dm-mono-400-latin.woff2") format("woff2");
}
@font-face {
  font-family: "DM Mono"; font-style: normal; font-weight: 500;
  font-display: swap; src: url("/fonts/dm-mono-500-latin.woff2") format("woff2");
}

/* schepens.cc — "Workshop Index" design system.
   Grounded in the brand mark: an ancient galley with a brick-red sail
   ("schepen" = Dutch for ships). Maritime logbook over sea-mist paper. */
:root {
  --bg: #e8eae7;            /* pale sea-mist paper */
  --surface: #fbfbf8;       /* sail white */
  --surface-inset: #f1f2ee;
  --ink: #1a1a1a;           /* hull black (matches icon) */
  --ink-soft: #5f6360;
  --ink-faint: #8b8f8b;
  --line: #dcded8;
  --line-strong: #c8cac3;
  --accent: #b15140;        /* brick-red sail */
  --accent-deep: #8f3e30;
  --accent-wash: rgba(177, 81, 64, 0.09);
  --ok-bg: #eef6f0; --ok-fg: #2c6a45; --ok-line: #c2dfcd;
  --warn-bg: #fdf3ea; --warn-fg: #9a4a1d; --warn-line: #f0d5bd;
  --radius: 12px;
  --radius-sm: 8px;
  --shadow: 0 1px 2px rgba(26, 26, 26, 0.05), 0 6px 18px -10px rgba(26, 26, 26, 0.18);
  --font-display: "Bricolage Grotesque", "Inter", system-ui, sans-serif;
  --font-body: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-mono: "DM Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /* How wide a column of running text or stacked inputs is allowed to get.
     The page frame is one width for every page (see .page-wrap); this is what
     keeps a paragraph or a form from being read across the whole of it. Roughly
     the px twin of the 60ch cap the Kompas walk uses on its own paragraphs. */
  --measure: 640px;
}

/*
  Responsive breakpoint scale — use these literal values in @media queries
  (CSS custom properties are not allowed inside @media). Prefer min-width
  (mobile-first); for the "below" half of a toggle use the tier minus 1px.
    sm  640px   phones → small tablets
    md  768px   tablets / narrow laptops
    lg 1024px   comfortable two-column desktop layouts
  All @media queries in the app use these tiers (or a tier minus 1px for
  the "below" half of a toggle). Reach for one of these, not a new number.
*/

*, *::before, *::after { box-sizing: border-box; }
body {
  font-family: var(--font-body);
  background: var(--bg);
  background-image: radial-gradient(circle at 1px 1px, rgba(26, 26, 26, 0.025) 1px, transparent 0);
  background-size: 22px 22px;
  color: var(--ink);
  margin: 0;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  line-height: 1.55;
}
a { color: var(--accent); text-decoration-color: rgba(177, 81, 64, 0.35); text-underline-offset: 0.18em; }
a:hover { color: var(--accent-deep); }

/* ── The content column ──
   Every page is this one width. There used to be a tier per page shape —
   880 for prose, 1100 for grids, 1180 for the galleries — and the result was
   that walking from the home page into Kompas visibly moved the masthead and
   the footer. One width costs a grid page a little room and buys a site that
   holds still, which is the better trade on a personal site.

   Readability is handled a level down instead: the frame is always 1000px,
   and the things that must not be read across 1000px (form columns, running
   prose) cap their own measure with --measure. So the page edges line up
   everywhere while the text stays comfortable — see .form-section below.

   1000px is deliberately under the lg tier (1024px), so no media query is
   needed: below that the viewport is already the limit.

   Side and bottom padding honour the device safe-area insets: installed
   on iOS the page runs edge to edge (viewport-fit=cover), so without
   these the footer sits under the home indicator and the masthead under
   the notch in landscape. env() resolves to 0 everywhere else, leaving
   the browser layout untouched. */
.page-wrap {
  max-width: 1000px; margin: 0 auto;
  padding: 2rem max(1.5rem, env(safe-area-inset-right)) calc(3rem + env(safe-area-inset-bottom)) max(1.5rem, env(safe-area-inset-left));
}
/* The one exception: the family tree is a canvas, not a document. */
.page-wrap--full { max-width: none; }

/* ── Masthead ── */
.topbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem 1.5rem; padding-bottom: 1rem; margin-bottom: 1.75rem;
  border-bottom: 1px solid var(--line);
  position: relative; font-size: 0.85rem;
}
.topbar::after {
  content: ""; position: absolute; left: 0; bottom: -1px; width: 56px;
  height: 2px; background: var(--accent);
}
.brand { display: inline-flex; align-items: center; gap: 0.6rem; color: var(--ink); font-family: var(--font-display); font-weight: 700; font-size: 1.05rem; letter-spacing: -0.01em; text-decoration: none; }
.brand .dot { color: var(--accent); }
.brand-mark { display: block; width: 2rem; height: 2rem; border-radius: 999px; box-shadow: 0 0 0 1px var(--line-strong); }

/* The installed app bar is a second shell context, not a small-screen
   masthead. Display-mode decides whether it exists; width only limits the
   first app-specific experience to the compact tier. */
.installed-app-bar { display: none; }
.app-bar-side { min-width: 44px; display: flex; align-items: center; }
.app-bar-leading { justify-content: flex-start; }
.app-bar-trailing { justify-content: flex-end; }
.app-bar-button, .app-bar-mark {
  width: 44px; height: 44px; display: inline-flex; align-items: center; justify-content: center;
  color: var(--ink); text-decoration: none; border-radius: 999px;
}
.app-bar-button { border: 1px solid var(--line); background: var(--surface); }
.app-bar-button:hover { color: var(--accent-deep); border-color: var(--accent); }
.app-bar-button svg { width: 24px; height: 24px; }
.app-bar-mark img { width: 2rem; height: 2rem; border-radius: 999px; box-shadow: 0 0 0 1px var(--line-strong); }
.app-bar-title {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  text-align: center; font-family: var(--font-display); font-weight: 700; font-size: 1rem;
}
.app-bar-signin {
  min-height: 44px; display: inline-flex; align-items: center; padding: 0 0.8rem;
  border-radius: 999px; background: var(--ink); color: #fff; text-decoration: none;
  font-size: 0.78rem; font-weight: 600; white-space: nowrap;
}
.app-bar-signin:hover { background: #000; color: #fff; }

/* Right side of the masthead: clustered nav + the account zone. */
.masthead-end { display: flex; align-items: center; gap: 1.25rem; flex-wrap: wrap; }

.nav { display: flex; align-items: center; gap: 1.15rem; flex-wrap: wrap; }
.nav-link { color: var(--ink-soft); text-decoration: none; position: relative; padding-bottom: 0.15rem; transition: color 0.12s; }
.nav-link::after { content: ""; position: absolute; left: 0; right: 100%; bottom: 0; height: 1.5px; background: var(--accent); transition: right 0.18s ease; }
.nav-link:hover { color: var(--ink); }
.nav-link:hover::after { right: 0; }

/* Admin tools, grouped into a disclosure menu. */
.nav-menu { position: relative; display: inline-flex; }
.nav-menu-trigger { font: inherit; font-size: 0.85rem; color: var(--ink-soft); background: none; border: none; padding: 0; cursor: pointer; display: inline-flex; align-items: center; gap: 0.3rem; transition: color 0.12s; }
.nav-menu-trigger:hover, .nav-menu-trigger[aria-expanded="true"] { color: var(--ink); }
.nav-menu-trigger .caret { font-size: 0.6rem; transition: transform 0.18s ease; }
.nav-menu-trigger[aria-expanded="true"] .caret { transform: rotate(180deg); }
.nav-menu-panel { position: absolute; top: calc(100% + 0.7rem); right: 0; min-width: 12.5rem; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-sm); box-shadow: 0 8px 28px -10px rgba(26,26,26,0.3), 0 1px 2px rgba(26,26,26,0.06); padding: 0.4rem; z-index: 50; }
.nav-menu-label { display: block; font-family: var(--font-mono); font-size: 0.6rem; text-transform: uppercase; letter-spacing: 0.12em; color: var(--ink-faint); padding: 0.35rem 0.6rem 0.3rem; }
.nav-menu-panel a { display: block; padding: 0.45rem 0.6rem; border-radius: 6px; color: var(--ink-soft); text-decoration: none; font-size: 0.85rem; white-space: nowrap; }
.nav-menu-panel a:hover { background: var(--surface-inset); color: var(--accent-deep); }

/* Account zone — set apart on the far right. */
.account-zone { display: flex; align-items: center; gap: 0.75rem; padding-left: 1.25rem; border-left: 1px solid var(--line); }
.account-zone form { margin: 0; }
.account { display: inline-flex; align-items: center; gap: 0.55rem; }
/* 44px hit area even on a pointer device — it is a small target otherwise, and
   the dot sitting proud of the icon makes the visual bounds misleading. */
.account-inbox { display: inline-flex; align-items: center; justify-content: center; min-width: 44px; min-height: 44px; color: var(--ink-soft); }
.account-inbox:hover { color: var(--accent-deep); }
.account-inbox svg { width: 20px; height: 20px; }
.account-avatar { flex: 0 0 auto; width: 1.95rem; height: 1.95rem; border-radius: 999px; background: var(--ink); color: #fff; display: inline-flex; align-items: center; justify-content: center; font-family: var(--font-display); font-weight: 700; font-size: 0.8rem; box-shadow: 0 0 0 1px var(--line-strong); }
.account-meta { display: inline-flex; flex-direction: column; line-height: 1.18; }
.account-name { font-weight: 600; font-size: 0.82rem; color: var(--ink); }
.account-role { font-family: var(--font-mono); font-size: 0.6rem; text-transform: uppercase; letter-spacing: 0.1em; color: var(--ink-faint); }
.account-signout { display: inline-flex; align-items: center; gap: 0.35rem; font: inherit; font-size: 0.78rem; font-weight: 600; color: var(--ink-soft); background: var(--surface); border: 1px solid var(--line-strong); border-radius: 999px; padding: 0.35rem 0.75rem; cursor: pointer; text-decoration: none; transition: color 0.12s, border-color 0.12s; }
.account-signout:hover { color: var(--accent-deep); border-color: var(--accent); }

/* Sign in (logged out). */
.nav-signin { display: inline-flex; align-items: center; min-height: 2.2rem; padding: 0.4rem 1rem; border-radius: 999px; border: 1px solid var(--ink); background: var(--ink); color: #fff; font-size: 0.82rem; font-weight: 600; text-decoration: none; transition: background 0.15s; }
.nav-signin:hover { background: #000; color: #fff; }

/* ── Flash ── */
.flash-notice, .flash-alert { border-radius: var(--radius-sm); padding: 0.7rem 1rem; margin-bottom: 1.5rem; font-size: 0.875rem; display: flex; gap: 0.5rem; }
.flash-notice { background: var(--ok-bg); color: var(--ok-fg); border: 1px solid var(--ok-line); }
.flash-alert  { background: #fbeeec; color: var(--accent-deep); border: 1px solid #eccabf; }

h1 { font-family: var(--font-display); font-size: 1.7rem; font-weight: 700; letter-spacing: -0.02em; margin: 0 0 1.5rem; line-height: 1.15; }
h2 { font-family: var(--font-display); letter-spacing: -0.01em; }
.eyebrow { font-family: var(--font-mono); font-size: 0.7rem; font-weight: 500; text-transform: uppercase; letter-spacing: 0.14em; color: var(--accent-deep); }
.muted { color: var(--ink-soft); }

.page-header { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-bottom: 1.5rem; }
.page-header h1 { margin: 0; }

/* ── Buttons ── */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 0.4rem; min-height: 2.5rem; padding: 0.55rem 1.05rem; border-radius: var(--radius-sm); border: 1px solid var(--ink); background: var(--ink); color: #fff; font-size: 0.85rem; font-weight: 600; text-decoration: none; cursor: pointer; font-family: var(--font-body); transition: transform 0.08s ease, box-shadow 0.15s ease, background 0.15s; }
.btn:hover { background: #000; box-shadow: 0 4px 14px -6px rgba(26,26,26,0.5); color: #fff; }
.btn:active { transform: translateY(1px); }
.btn-secondary { background: var(--surface); color: var(--ink); border-color: var(--line-strong); }
.btn-secondary:hover { background: var(--surface); color: var(--accent-deep); border-color: var(--accent); box-shadow: none; }
/* Still 44px tall — the touch-target minimum applies to a secondary action
   just as much, so this trims the padding and type rather than the height. */
.btn-small { min-height: 44px; padding: 0.35rem 0.7rem; font-size: 0.75rem; }
.btn-danger { background: var(--surface); color: var(--accent-deep); border-color: #d9b3aa; }
.btn-danger:hover { background: var(--accent); color: #fff; border-color: var(--accent); }

/* ── Forms ── */
.form-group { margin-bottom: 1.1rem; }
.form-group label { display: block; font-size: 0.82rem; font-weight: 600; margin-bottom: 0.4rem; }
.form-group input, .form-group select, .form-group textarea { display: block; width: 100%; border: 1px solid var(--line-strong); border-radius: var(--radius-sm); padding: 0.55rem 0.8rem; font: inherit; font-size: 0.9rem; background: var(--surface); color: var(--ink); transition: border-color 0.12s, box-shadow 0.12s; }
.form-group input:focus, .form-group select:focus, .form-group textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-wash); }
.form-group input.mono, .form-group textarea.mono { font-family: var(--font-mono); font-size: 0.85rem; }
.form-hint { font-size: 0.8rem; color: var(--ink-soft); margin-top: 0.35rem; }
.form-errors { background: #fbeeec; color: var(--accent-deep); border: 1px solid #eccabf; border-radius: var(--radius-sm); padding: 0.7rem 1rem; margin-bottom: 1rem; font-size: 0.875rem; }

/* Capped rather than full-bleed: a stack of inputs read across the whole
   1000px frame is worse than one read across 640px, and the page edges still
   line up with every other page because the frame itself is unchanged. Inside
   a two-column layout (the routine form, a run) the column is already narrower
   than this, so the cap simply doesn't apply there. */
.form-section { max-width: var(--measure); border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); padding: 1.1rem 1.25rem 0.2rem; margin: 0 0 1.25rem; box-shadow: var(--shadow); }
.form-section legend { font-family: var(--font-mono); font-size: 0.7rem; font-weight: 500; text-transform: uppercase; letter-spacing: 0.12em; color: var(--accent-deep); padding: 0 0.4rem; }
.form-row { display: grid; grid-template-columns: 2fr 1fr; gap: 0.85rem; }
.form-group .form-check { display: flex; align-items: baseline; gap: 0.5rem; font-size: 0.9rem; font-weight: 400; margin-bottom: 0; }
.form-group .form-check input { display: inline; width: auto; }
.form-check strong { font-size: 0.9rem; }
.form-advanced { margin: 0 0 1.5rem; }
.form-advanced summary { cursor: pointer; font-size: 0.9rem; font-weight: 600; }
.form-advanced summary .summary-note { font-weight: 400; color: var(--ink-soft); }
.form-advanced-body { margin-top: 1rem; padding-left: 1rem; border-left: 2px solid var(--line); }
.form-actions { display: flex; align-items: center; gap: 1rem; }

/* ── Breadcrumb + routine quick-switcher ── */
.breadcrumb { display: flex; align-items: center; flex-wrap: wrap; gap: 0.35rem; font-size: 0.82rem; margin-bottom: 1.1rem; color: var(--ink-soft); }
.breadcrumb-link { color: var(--ink-soft); text-decoration: none; }
.breadcrumb-link:hover { color: var(--accent-deep); }
.breadcrumb-current { color: var(--ink); font-weight: 600; }
.breadcrumb-sep { color: var(--ink-faint); }
.breadcrumb-switcher { position: relative; display: inline-flex; }
.breadcrumb-switcher-trigger { display: inline-flex; align-items: center; gap: 0.25rem; background: none; border: none; padding: 0; margin: 0; font: inherit; font-size: 0.82rem; font-weight: 600; color: var(--ink); cursor: pointer; }
.breadcrumb-switcher-trigger:hover { color: var(--accent-deep); }
.breadcrumb-caret { font-size: 0.7rem; color: var(--ink-soft); }
.breadcrumb-switcher-panel { position: absolute; top: 100%; left: 0; margin-top: 0.4rem; min-width: 13rem; max-height: 18rem; overflow-y: auto; background: var(--surface); border: 1px solid var(--line-strong); border-radius: var(--radius-sm); box-shadow: 0 10px 28px -10px rgba(26,26,26,0.45); padding: 0.3rem; z-index: 60; }
.breadcrumb-switcher-item { display: block; padding: 0.4rem 0.6rem; border-radius: var(--radius-sm); font-size: 0.85rem; color: var(--ink); text-decoration: none; white-space: nowrap; }
.breadcrumb-switcher-item:hover { background: var(--accent-wash); color: var(--accent-deep); }
.breadcrumb-switcher-item.is-current { font-weight: 700; }

/* Routine form: single column by default, two columns on large screens.
   Left holds Task + Repository, right holds GitHub/Schedule/Advanced. */
.routine-form-cols { display: grid; grid-template-columns: 1fr; column-gap: 1.5rem; align-items: start; }
.form-actions-top { margin-bottom: 1.25rem; }
.routine-prompt { min-height: 18rem; resize: vertical; }
@media (min-width: 1024px) {
  .routine-form-cols { grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr); }
}

/* Show pages (routine/run) reuse .form-section as a read-only card: a
   .section-title heading stands in for the <legend> a real fieldset would
   carry, and .detail-field pairs replace inputs. Mirrors the edit page. */
.form-section.is-info { padding: 1.1rem 1.25rem; }
.section-title { font-family: var(--font-mono); font-size: 0.7rem; font-weight: 500; text-transform: uppercase; letter-spacing: 0.12em; color: var(--accent-deep); margin: 0 0 0.9rem; }
.detail-field + .detail-field { margin-top: 0.9rem; }
.detail-field .label { font-family: var(--font-mono); font-size: 0.68rem; font-weight: 500; text-transform: uppercase; letter-spacing: 0.08em; color: var(--ink-soft); margin-bottom: 0.2rem; }
.detail-field .value { word-break: break-word; font-size: 0.9rem; }
.mono { font-family: var(--font-mono); }

/* Run mode radios and the live cron preview on the routine form. */
.run-mode-options { display: flex; flex-direction: column; gap: 0.6rem; }
.run-mode-option { align-items: flex-start; }
.run-mode-option span span { display: block; }
.cron-preview { margin-top: 0.5rem; }
.cron-preview-label { font-size: 0.75rem; font-weight: 600; color: var(--ink-soft); margin: 0 0 0.25rem; }
.cron-preview-list { list-style: none; margin: 0; padding: 0; font-size: 0.82rem; }
.cron-preview-list li { display: flex; gap: 0.5rem; padding: 0.1rem 0; font-family: var(--font-mono); }
.cron-preview-error { font-size: 0.82rem; color: var(--accent-deep); }

/* ── Status badges ── */
.badge { display: inline-block; font-size: 0.7rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em; padding: 0.12rem 0.45rem; border-radius: 999px; border: 1px solid transparent; }
.badge-ok { background: #f0fdf4; color: #166534; border-color: #bbf7d0; }
.badge-fail { background: #fef2f2; color: #991b1b; border-color: #fecaca; }
.badge-warn { background: #fff7ed; color: #9a3412; border-color: #fed7aa; }
.badge-pending { background: #fffbeb; color: #92400e; border-color: #fde68a; }
.badge-neutral { background: #f3f4f6; color: #374151; border-color: #e5e7eb; }
.muted { color: var(--ink-soft); }

/* ── Launcher plates ──
   The homepage launcher and the section pages both list Surface tiles,
   so the plate lives here rather than in either view. */
.harbour-label { display: flex; align-items: center; gap: 0.8rem; margin: 0 0 1.1rem; }
.harbour-label .eyebrow { white-space: nowrap; }
.harbour-label::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.harbour-label:not(:first-of-type) { margin-top: 2.25rem; }

.grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem; }

.plate {
  display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 1.25rem 1.3rem 1.1rem;
  text-decoration: none; color: var(--ink);
  box-shadow: var(--shadow);
  transition: transform 0.16s ease, box-shadow 0.16s ease, border-color 0.16s ease;
}
.plate:hover {
  transform: translateY(-2px); border-color: var(--line-strong);
  color: var(--ink);
  box-shadow: 0 2px 4px rgba(26,26,26,0.05), 0 16px 30px -16px rgba(26,26,26,0.32);
}
.plate-tier { display: inline-flex; align-self: flex-start; }
.tier {
  font-family: var(--font-mono); font-size: 0.62rem; font-weight: 500;
  text-transform: uppercase; letter-spacing: 0.14em;
  padding: 0.18rem 0.5rem; border-radius: 999px;
  border: 1px solid var(--line-strong); color: var(--ink-soft); background: var(--surface-inset);
}
.tier-gezin  { color: var(--ok-fg);   border-color: var(--ok-line);   background: var(--ok-bg); }
.tier-admin  { color: var(--accent-deep); border-color: #e2c4bc; background: var(--accent-wash); }
.plate h2 { font-size: 1.2rem; font-weight: 700; margin: 0.85rem 0 0.35rem; }
.plate p { color: var(--ink-soft); font-size: 0.9rem; line-height: 1.5; margin: 0; }
.plate-go {
  display: inline-flex; align-items: center; gap: 0.45rem;
  margin-top: 1rem; font-size: 0.82rem; font-weight: 600; color: var(--accent-deep);
}
.plate-go .arrow { transition: transform 0.18s ease; }
.plate:hover .plate-go .arrow { transform: translateX(4px); }

/* ── Mobile tab bar ──
   Hidden at md and up, where the masthead does the same job. Shown below
   it as a fixed bottom bar: thumb-reachable, and the only persistent way
   back when the site is running installed with no browser chrome. */
.tab-bar {
  display: none;
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  background: var(--surface);
  border-top: 1px solid var(--line);
  padding-bottom: env(safe-area-inset-bottom);
  box-shadow: 0 -10px 24px -20px rgba(26, 26, 26, 0.55);
}
.tab-bar-inner { display: flex; }
.tab {
  flex: 1 1 0; min-width: 0; min-height: 54px;
  display: inline-flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 0.2rem; padding: 0.4rem 0.25rem;
  position: relative;
  color: var(--ink-soft); text-decoration: none;
  font-size: 0.66rem; font-weight: 600;
}
.tab svg { width: 22px; height: 22px; }

/* The positioning context an .unread-dot anchors to. Deliberately not scoped
   to .tab: the same wrapper is used by the installed app bar and the desktop
   masthead, and without position:relative the dot escapes to the nearest
   positioned ancestor — in practice the fixed app bar, i.e. the screen corner. */
.badged-icon { position: relative; display: inline-flex; }

/* ── Unread marker ──
   Rides the corner of a shell icon (the Me tab, the installed app bar's
   inbox button). Sized to stay legible at "9+" without crowding a 22px
   icon; the surface-coloured ring keeps it readable over the icon strokes. */
.unread-dot {
  position: absolute; top: -4px; right: -7px;
  min-width: 16px; height: 16px; padding: 0 4px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 999px;
  background: var(--accent); color: #fff;
  border: 2px solid var(--surface);
  font-family: var(--font-mono); font-size: 0.6rem; font-weight: 500; line-height: 1;
}

/* Text for screen readers only — the unread count is a coloured dot to the
   eye, which announces as nothing without this. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}
/* Scoped to the label, not every span in the tab: the badge wrapper is a span
   too, and the dot sits outside its box on purpose, so `overflow: hidden` here
   would clip it. */
.tab-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
.tab[aria-current="page"] { color: var(--accent-deep); }
.tab[aria-current="page"]::before {
  content: ""; position: absolute; top: 0; left: 50%; transform: translateX(-50%);
  width: 28px; height: 2px; background: var(--accent);
}

/* ── Footer ── */
.site-footer { margin-top: 3rem; padding-top: 1.25rem; border-top: 1px solid var(--line); display: flex; justify-content: space-between; align-items: center; gap: 1rem; flex-wrap: wrap; font-family: var(--font-mono); font-size: 0.72rem; color: var(--ink-faint); }
.site-footer a { color: var(--ink-faint); text-decoration: none; }
.site-footer a:hover { color: var(--accent-deep); }

@media (max-width: 639px) {
  .page-wrap {
    padding: 1.5rem max(1.15rem, env(safe-area-inset-right)) calc(2.5rem + env(safe-area-inset-bottom)) max(1.15rem, env(safe-area-inset-left));
  }
  .page-wrap--full { padding-top: 1.25rem; padding-inline: 1.25rem; }
  .topbar { align-items: stretch; flex-direction: column; gap: 1rem; }
  .masthead-end { flex-direction: column; align-items: flex-start; gap: 1rem; width: 100%; }
  .account-zone { width: 100%; justify-content: space-between; padding-left: 0; border-left: 0; padding-top: 0.9rem; border-top: 1px solid var(--line); }
  .nav-menu-panel { left: 0; right: auto; }
  .form-row { grid-template-columns: 1fr; gap: 0; }

  /* Touch targets: 0.85rem text leaves a hit area well under the 44px
     minimum, which is the difference between tapping a control and
     tapping the gap next to it. */
  .brand, .nav-signin { min-height: 44px; }

  /* Compact launcher tiles. At full size, nine plates run to roughly
     three screens of scrolling — and more apps are coming. The blurb and
     the call to action are what a phone can afford to drop: the whole
     tile is the link, so the arrow was only restating that. */
  .grid { gap: 0.7rem; }
  .plate { padding: 0.85rem 0.9rem 1rem; }
  .plate h2 { font-size: 1rem; margin: 0.55rem 0 0; }
  .plate p, .plate-go { display: none; }
}

/* Below md the tab bar takes over navigation, so the masthead sheds its
   nav links and account zone — together they were eating most of the
   first screen — and keeps only the brand (plus Sign in when signed out,
   since anonymous visitors get no tab bar). */
@media (max-width: 767px) {
  .tab-bar { display: block; }
  .topbar .nav, .topbar .account-zone { display: none; }
  .topbar { flex-direction: row; align-items: center; }
  .masthead-end { width: auto; flex-direction: row; align-items: center; }

  /* Clear the fixed bar. Declared after the sm block so it wins over the
     padding shorthand there. */
  .page-wrap { padding-bottom: calc(2.5rem + 54px + env(safe-area-inset-bottom)); }
}

/* ── Page feedback trigger ──
   The engine's floating "Give page feedback" button is fixed to the bottom
   right, which is exactly where the tab bar sits below md. Two rules split
   it by viewport, matching the tab-bar breakpoint:

   Below md the button stays — a phone has no Alt+F — but is lifted clear of
   the 54px tab bar. The engine adds env(safe-area-inset-bottom) on top of
   this offset itself, and the tab bar's own safe-area padding is the same
   inset, so the two line up.

   The offset is declared on `body`, not `:root`, for two reasons. The engine
   stylesheet loads after ours (page_feedback_head has to follow
   javascript_importmap_tags), so a competing `:root` rule here would lose to
   the engine's own defaults — but `body` is a different element, so it simply
   wins for everything inside it, and the trigger, the capture-mode indicator
   and the toasts are all body children. It also leaves a clean way for one
   page to raise the offset further; see .kompas-fab in kompas.css.

   At md and up the button is hidden. Alt+F still opens capture, and on a
   desktop the persistent button is just chrome sitting over every page.

   It comes back the moment capture is armed, because the engine turns this same
   button into the capture-mode banner (`--active`) rather than floating a
   separate indicator beside it. It only floats the standalone indicator when
   the trigger is absent from the DOM, which is `config.trigger_visible = false`
   — and we hide ours in CSS instead, so a plain `display: none` at md and up
   left desktop with no sign that Alt+F had done anything. Unhiding the active
   modifier gets the best of both: no chrome until you ask for capture, then the
   button says which mode you are in and how to leave it. */
@media (max-width: 767px) {
  body { --page-feedback-offset-bottom: calc(54px + 0.75rem); }
}

@media (min-width: 768px) {
  .page-feedback-widget__trigger { display: none; }
  .page-feedback-widget__trigger--active { display: revert; }
}

/* Compact installed mode owns its chrome. Browser-mobile keeps the website
   masthead and footer; installed-mobile replaces them with this app bar. */
@media (max-width: 767px) and (display-mode: standalone),
       (max-width: 767px) and (display-mode: minimal-ui) {
  body {
    overscroll-behavior-y: none;
    -webkit-tap-highlight-color: transparent;
  }
  .browser-masthead, .browser-footer { display: none; }
  .installed-app-bar {
    display: grid; grid-template-columns: minmax(44px, auto) minmax(0, 1fr) minmax(44px, auto);
    align-items: center; gap: 0.75rem; min-height: 56px;
    padding-top: env(safe-area-inset-top); margin-bottom: 1.5rem;
    border-bottom: 1px solid var(--line);
  }
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
}
