/* ══════════════════════════════════════════════════════════════════════════════════════════════
   ui.css — Floody's component layer (the UI kit). Every component of both panels is defined HERE,
   once, from the tokens in tokens.css. Templates compose these classes and add Tailwind utilities
   only for LAYOUT (flex, grid, gap, margin, width). See docs/design-system.md.

   WHY A STATIC FILE: markup built by script (toasts, the datepicker, the builders, htmx swaps) is
   never scanned by the browser Tailwind build, so a component written as a utility chain has no
   rule behind it there. Plain CSS always has. It is also cached, where the inline theme is not.

   CASCADE: the layer order is declared first, so `components` sits above Tailwind's preflight
   (`base`) and BELOW `utilities` — `class="btn btn-primary w-full"` lets `w-full` win, which is
   exactly what a component class should allow.
   ══════════════════════════════════════════════════════════════════════════════════════════════ */
@layer theme, base, components, utilities;

/* ─────────────────────────────────────────────────────────────────────────────────────────────
   BASE
   ───────────────────────────────────────────────────────────────────────────────────────────── */
@layer base {
  html {
    font-family: var(--font-sans);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
    -webkit-tap-highlight-color: transparent;
  }
  body {
    min-height: 100vh;
    background: var(--color-canvas);
    color: var(--color-text-primary);
    font-size: var(--text-sm);
    line-height: var(--text-sm--line-height);
  }
  ::selection { background: var(--color-accent-soft); color: var(--color-text-primary); }

  a[href], button:not(:disabled), [role='button'], [onclick], summary, label[for],
  input[type='checkbox'], input[type='radio'], input[type='range'], select,
  [data-tab-trigger] { cursor: pointer; }
  button:disabled, [aria-disabled='true'] { cursor: not-allowed; }

  /* One focus treatment for the whole product: a soft accent ring, keyboard only. */
  :where(a[href], button, [role='button'], [data-tab-trigger], summary, input, select, textarea, [tabindex]):focus { outline: none; }
  :where(a[href], button, [role='button'], [data-tab-trigger], summary, [tabindex]):focus-visible { box-shadow: var(--shadow-focus); }

  /* Native checkboxes, radios and ranges wear the ink, everywhere, with no class needed. */
  input[type='checkbox'], input[type='radio'] { accent-color: var(--color-primary); width: 16px; height: 16px; }

  /* Scrollbars: thin and quiet rather than hidden. A hidden scrollbar hides the fact that an
     area scrolls at all; Windows' default bar is a slab. This is the middle. */
  * { scrollbar-width: thin; scrollbar-color: var(--color-border-dark) transparent; }
  ::-webkit-scrollbar { width: 8px; height: 8px; }
  ::-webkit-scrollbar-track { background: transparent; }
  ::-webkit-scrollbar-thumb { background: var(--color-border-medium); border-radius: 9999px; border: 2px solid transparent; background-clip: padding-box; }
  ::-webkit-scrollbar-thumb:hover { background-color: var(--color-border-dark); }

  html { scroll-behavior: smooth; }

  /* A grid with no column template gets ONE shrinkable column. Without this the implicit `auto`
     track grows to its widest child's min-content, so a `truncate` line inside (a long slug, a
     URL) widens the whole page on a phone. Every grid-cols-* utility still wins (utilities layer). */
  .grid { grid-template-columns: minmax(0, 1fr); }

  @media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
      animation-duration: 0.001ms !important;
      animation-iteration-count: 1 !important;
      transition-duration: 0.001ms !important;
      scroll-behavior: auto !important;
    }
    /* Spinners are functional, not decorative: they keep turning. */
    .kit-spin, .kit-spinner { animation-duration: 0.7s !important; animation-iteration-count: infinite !important; }
  }
}

/* ─────────────────────────────────────────────────────────────────────────────────────────────
   COMPONENTS
   ───────────────────────────────────────────────────────────────────────────────────────────── */
@layer components {

  /* ── Utilities that are really components (no Tailwind equivalent) ────────────────────────── */
  .rtl-inline-meta { direction: rtl; unicode-bidi: isolate; }
  .ltr-data { direction: ltr; unicode-bidi: plaintext; }
  /* Persian words inside a code sample: the monospace faces have no Persian, so they keep the sans face. */
  .code-fa { font-family: var(--font-sans); }
  .kit-break { overflow-wrap: anywhere; word-break: normal; }
  .scroll-hide, .kit-scroll-x { scrollbar-width: none; -ms-overflow-style: none; }
  .scroll-hide::-webkit-scrollbar, .kit-scroll-x::-webkit-scrollbar { display: none; }
  /* Numbers. NOT tabular figures: Vazirmatn's tabular Persian digits open visible gaps («۱ ۰ ۰»),
     so figures stay proportional and a number simply never wraps. */
  .num { white-space: nowrap; }

  @keyframes pulseDot { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: 0.5; transform: scale(1.3); } }
  .pulse-dot { animation: pulseDot 1.6s ease-in-out infinite; }

  /* ── Surfaces ──────────────────────────────────────────────────────────────────────────────
     `.card` is THE container. `.glass-panel` is its legacy name: it used to be a frosted,
     blurred sheet; it is now the same solid surface, so nothing written against it breaks. */
  .card, .glass-panel {
    background: var(--color-bg-primary);
  }
  .card {
    border: 1px solid var(--color-border-light);
    border-radius: var(--radius-card);
    box-shadow: var(--shadow-card);
  }
  .card-header {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    min-height: 56px; padding: 12px 20px;
    border-bottom: 1px solid var(--color-border-light);
  }
  .card-title {
    display: flex; align-items: center; gap: 8px;
    font-size: var(--text-base); line-height: 1.5; font-weight: 600; color: var(--color-text-primary);
  }
  .card-title > i { font-size: var(--text-xs); color: var(--color-text-muted); }
  .card-subtitle { margin-top: 2px; font-size: var(--text-xs); line-height: 1.6; color: var(--color-text-muted); }
  .card-body { padding: 20px; }
  .card-footer {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    padding: 12px 20px;
    border-top: 1px solid var(--color-border-light);
    background: var(--color-bg-secondary);
    border-end-start-radius: inherit; border-end-end-radius: inherit;
  }
  @media (max-width: 639px) {
    .card-header { padding: 12px 16px; }
    .card-body { padding: 16px; }
    .card-footer { padding: 12px 16px; }
  }
  a.card, .card-interactive { transition: border-color var(--duration-fast) var(--ease-standard), box-shadow var(--duration-fast) var(--ease-standard); }
  a.card:hover, .card-interactive:hover { border-color: var(--color-border-dark); box-shadow: var(--shadow-sm); }

  /* A quiet panel INSIDE a card: KPI tiles, grouped settings, read-only blocks. */
  .tile {
    background: var(--color-bg-secondary);
    border: 1px solid var(--color-border-light);
    border-radius: var(--radius-2xl);
    padding: 12px 16px;
  }

  /* ── Drop zone ── a file picker a file can also be dropped on (the flow's Excel import). The
     zone is the <label> of a visually hidden file input, so a click, a tap and the keyboard all
     open the picker; `.is-over` while a file is dragged over it. */
  .drop-zone {
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
    padding: 20px 16px; text-align: center; cursor: pointer;
    background: var(--color-bg-secondary);
    border: 1px dashed var(--color-border-dark);
    border-radius: var(--radius-2xl);
    transition: border-color var(--duration-fast) var(--ease-standard), background-color var(--duration-fast) var(--ease-standard);
  }
  .drop-zone:hover, .drop-zone.is-over { border-color: var(--color-accent-line); background: var(--color-accent-soft); }
  .drop-zone:focus-within { box-shadow: var(--shadow-focus); }
  /* Once a file is in: one row (icon, name, size, «تغییر فایل»). Still a drop target. */
  .drop-zone.is-filled { flex-direction: row; justify-content: flex-start; gap: 10px; padding: 12px 16px; text-align: start; border-style: solid; }

  /* ── Import tally ── what a chosen file holds, at the start of the import dialog's footer.
     The numbers run up to their value (`--duration-count`, in lead-import.js). */
  @keyframes tally-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
  .import-tally { display: flex; flex-direction: column; gap: 2px; min-width: 0; margin-inline-end: auto; animation: tally-in var(--duration-slow) var(--ease-standard); }
  .import-tally-main { font-size: var(--text-md); line-height: 1.5; font-weight: 700; color: var(--color-text-primary); }
  .import-tally-main .num { color: var(--color-success-strong); }
  .import-tally-sub { font-size: var(--text-2xs); line-height: 1.6; color: var(--color-text-muted); }
  .import-tally-sub .num { color: var(--color-text-secondary); font-weight: 600; }
  .import-tally.is-empty .import-tally-main .num { color: var(--color-danger-strong); }
  @media (max-width: 640px) { .import-tally { flex-basis: 100%; } }

  /* ── Import column picker ── the first rows of a file with more than two columns; the chosen
     mobile and name columns are tinted and labelled in the head. Scrolls sideways on its own. */
  .import-grid-wrap { overflow-x: auto; border: 1px solid var(--color-border-light); border-radius: var(--radius-xl); }
  .import-grid { width: 100%; border-collapse: collapse; font-size: var(--text-2xs); }
  .import-grid th, .import-grid td { padding: 8px 12px; text-align: start; white-space: nowrap; max-width: 12rem; overflow: hidden; text-overflow: ellipsis; }
  .import-grid th { font-weight: 600; color: var(--color-text-secondary); background: var(--color-bg-secondary); border-bottom: 1px solid var(--color-border-light); }
  .import-grid td { color: var(--color-text-primary); border-top: 1px solid var(--color-border-light); }
  .import-grid tbody tr:first-child td { border-top: 0; }
  .import-grid .is-picked { background: var(--color-accent-soft); }
  .import-grid th.is-picked { color: var(--color-accent-strong); }
  .import-grid-tag { display: block; font-size: var(--text-2xs); font-weight: 500; color: var(--color-accent-strong); }

  /* ── Page scaffolding ──────────────────────────────────────────────────────────────────────── */
  .page { width: 100%; max-width: var(--content-max); margin-inline: auto; }
  .page-header {
    display: flex; flex-direction: column; gap: 12px; margin-bottom: 24px;
  }
  @media (min-width: 640px) {
    .page-header { flex-direction: row; align-items: flex-end; justify-content: space-between; gap: 16px; }
  }
  .page-title { font-size: var(--text-xl); line-height: 1.45; font-weight: 700; color: var(--color-text-primary); letter-spacing: -0.005em; }
  @media (min-width: 640px) { .page-title { font-size: var(--text-2xl); line-height: 1.4; } }
  .page-subtitle { margin-top: 4px; max-width: 46rem; font-size: var(--text-sm); line-height: 1.75; color: var(--color-text-muted); }
  .page-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; flex-shrink: 0; }

  .section-title { font-size: var(--text-base); line-height: 1.5; font-weight: 600; color: var(--color-text-primary); }
  .section-subtitle { margin-top: 2px; font-size: var(--text-xs); line-height: 1.65; color: var(--color-text-muted); }
  .eyebrow { font-size: var(--text-2xs); font-weight: 500; color: var(--color-text-muted); }

  /* ── Buttons ───────────────────────────────────────────────────────────────────────────────
     Size:    .btn-sm (34) · .btn (38) · .btn-lg (44)       Shape: .btn-icon (square)
     Variant: .btn-primary · .btn-secondary · .btn-ghost · .btn-danger · .btn-danger-ghost · .btn-link
     One primary button per view. Destructive actions are never primary-coloured. */
  .btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    box-sizing: border-box; height: var(--control-h); padding-inline: 16px;
    border: 1px solid transparent; border-radius: var(--radius-control);
    font-family: inherit; font-size: var(--text-sm); font-weight: 600; line-height: 1;
    white-space: nowrap; text-decoration: none; user-select: none;
    background: var(--color-bg-primary); color: var(--color-text-primary);
    transition: background-color var(--duration-fast) var(--ease-standard), border-color var(--duration-fast) var(--ease-standard),
                color var(--duration-fast) var(--ease-standard), box-shadow var(--duration-fast) var(--ease-standard);
  }
  .btn > i, .btn > [data-icon] > i { font-size: 0.9em; }
  .btn:focus-visible { box-shadow: var(--shadow-focus); }
  .btn:disabled, .btn[aria-disabled='true'] { opacity: 0.5; pointer-events: none; }
  .btn-sm { height: var(--control-h-sm); padding-inline: 12px; gap: 6px; font-size: var(--text-xs); border-radius: var(--radius-lg); }
  .btn-lg { height: var(--control-h-lg); padding-inline: 20px; font-size: var(--text-base); }
  .btn-icon { width: var(--control-h); padding-inline: 0; }
  .btn-icon.btn-sm { width: var(--control-h-sm); }
  .btn-icon.btn-lg { width: var(--control-h-lg); }
  .btn-block { display: flex; width: 100%; }

  .btn-primary { background: var(--color-primary); color: var(--color-on-primary); box-shadow: var(--shadow-button); }
  .btn-primary:hover { background: var(--color-primary-hover); }
  .btn-secondary { background: var(--color-bg-primary); color: var(--color-text-primary); border-color: var(--color-border-medium); box-shadow: var(--shadow-xs); }
  .btn-secondary:hover { background: var(--color-bg-secondary); border-color: var(--color-border-dark); }
  .btn-ghost { background: transparent; color: var(--color-text-secondary); }
  .btn-ghost:hover { background: var(--color-bg-tertiary); color: var(--color-text-primary); }
  .btn-danger { background: var(--color-danger); color: var(--color-white); box-shadow: var(--shadow-button); }
  .btn-danger:hover { background: var(--color-danger-strong); }
  .btn-danger:focus-visible { box-shadow: var(--shadow-focus-danger); }
  .btn-danger-ghost { background: transparent; color: var(--color-text-muted); }
  .btn-danger-ghost:hover { background: var(--color-danger-soft); color: var(--color-danger-strong); }
  .btn-link { height: auto; padding: 0; border: 0; background: none; color: var(--color-accent-strong); font-weight: 500; }
  .btn-link:hover { text-decoration: underline; text-underline-offset: 3px; }

  /* ── Links ─────────────────────────────────────────────────────────────────────────────────── */
  .link { color: var(--color-accent-strong); font-weight: 500; text-decoration: none; }
  .link:hover { text-decoration: underline; text-underline-offset: 3px; }
  .link-muted { color: var(--color-text-secondary); text-decoration: none; }
  .link-muted:hover { color: var(--color-text-primary); }

  /* ── Form controls ─────────────────────────────────────────────────────────────────────────
     `.input` covers <input>, <select> and <textarea>. Invalid state hangs off aria-invalid, so
     the server's validation and the styling cannot disagree. */
  .field { display: flex; flex-direction: column; gap: 6px; }
  .field-label { display: inline-flex; align-items: center; gap: 6px; font-size: var(--text-xs); font-weight: 500; line-height: 1.5; color: var(--color-text-primary); }
  .field-required { color: var(--color-danger); }
  .field-help { font-size: var(--text-2xs); line-height: 1.6; color: var(--color-text-muted); }
  .field-error { display: flex; align-items: center; gap: 4px; font-size: var(--text-2xs); line-height: 1.6; color: var(--color-danger-strong); }

  .input {
    box-sizing: border-box; display: block; width: 100%;
    height: var(--control-h); padding: 0 12px;
    border: 1px solid var(--color-border-medium); border-radius: var(--radius-control);
    background: var(--color-bg-primary); color: var(--color-text-primary);
    font-family: inherit; font-size: var(--text-sm); line-height: 1.5;
    box-shadow: var(--shadow-xs);
    transition: border-color var(--duration-fast) var(--ease-standard), box-shadow var(--duration-fast) var(--ease-standard);
  }
  .input::placeholder { color: var(--color-text-disabled); }
  /* An LTR field (a key, a username, a code) whose hint is Persian: the hint reads right to left
     at the right while the box is empty, and what is typed stays LTR. */
  .input-hint-rtl:placeholder-shown { direction: rtl; }
  .input:hover { border-color: var(--color-border-dark); }
  .input:focus, .input:focus-visible { outline: none; border-color: var(--color-accent); box-shadow: var(--shadow-focus); }
  .input:disabled, .input[readonly] { background: var(--color-bg-secondary); color: var(--color-text-secondary); box-shadow: none; }
  .input:disabled { cursor: not-allowed; }
  .input[aria-invalid='true'] { border-color: var(--color-danger); }
  .input[aria-invalid='true']:focus { box-shadow: var(--shadow-focus-danger); }
  textarea.input { height: auto; min-height: 88px; padding: 9px 12px; line-height: 1.75; resize: vertical; }
  select.input {
    -webkit-appearance: none; -moz-appearance: none; appearance: none;
    padding-inline-end: 34px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%2364748b' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 6l4 4 4-4'/%3E%3C/svg%3E");
    background-repeat: no-repeat; background-size: 14px 14px; background-position: left 12px center;
  }
  select.input[multiple] { height: auto; padding: 6px; background-image: none; }
  .input-sm { height: var(--control-h-sm); font-size: var(--text-xs); border-radius: var(--radius-lg); padding: 0 10px; }
  select.input-sm { padding-inline-end: 30px; background-position: left 10px center; }
  textarea.input-sm { padding: 7px 10px; }

  /* A control with a fixed affix drawn inside its leading edge (e.g. «/h/» before a slug). */
  .input-affix { position: relative; }
  .input-affix > .input-affix-text {
    position: absolute; inset-block: 0; left: 0; display: flex; align-items: center; padding-left: 12px;
    font-size: var(--text-xs); color: var(--color-text-muted); pointer-events: none; direction: ltr;
  }

  /* ── Badges ────────────────────────────────────────────────────────────────────────────────
     Status and categorical labels. Soft fill + strong ink, always ≥ 4.5:1. Add `.badge-dot`
     for a leading dot in the tone's base colour. */
  .badge {
    display: inline-flex; align-items: center; gap: 5px; box-sizing: border-box;
    height: 22px; padding-inline: 8px; border-radius: 9999px;
    border: 1px solid var(--color-neutral-line);
    background: var(--color-neutral-soft); color: var(--color-neutral-strong);
    font-size: var(--text-2xs); font-weight: 500; line-height: 1; white-space: nowrap;
  }
  .badge > i { font-size: 0.85em; }
  .badge-success { background: var(--color-success-soft); color: var(--color-success-strong); border-color: var(--color-success-line); }
  .badge-warning { background: var(--color-warning-soft); color: var(--color-warning-strong); border-color: var(--color-warning-line); }
  .badge-danger  { background: var(--color-danger-soft);  color: var(--color-danger-strong);  border-color: var(--color-danger-line); }
  .badge-info, .badge-accent { background: var(--color-accent-soft); color: var(--color-accent-strong); border-color: var(--color-accent-line); }
  .badge-neutral { background: var(--color-neutral-soft); color: var(--color-neutral-strong); border-color: var(--color-neutral-line); }
  .badge-solid { background: var(--color-primary); color: var(--color-on-primary); border-color: var(--color-primary); }
  .badge-outline { background: var(--color-bg-primary); color: var(--color-text-secondary); border-color: var(--color-border-medium); }
  .badge-dot::before { content: ''; width: 6px; height: 6px; border-radius: 9999px; background: currentColor; opacity: 0.85; flex: none; }
  .badge-lg { height: 26px; padding-inline: 10px; font-size: var(--text-xs); }

  /* Neutral selectable chip (filters, tags in a picker). */
  .chip {
    display: inline-flex; align-items: center; gap: 6px; height: 28px; padding-inline: 10px;
    border: 1px solid var(--color-border-medium); border-radius: 9999px;
    background: var(--color-bg-primary); color: var(--color-text-secondary);
    font-size: var(--text-2xs); font-weight: 500; white-space: nowrap;
  }
  .chip:hover { border-color: var(--color-border-dark); color: var(--color-text-primary); }
  .chip.is-active, .chip[aria-pressed='true'] { background: var(--color-primary); border-color: var(--color-primary); color: var(--color-on-primary); }

  /* ── Alerts (inline notices) ───────────────────────────────────────────────────────────────── */
  .alert {
    display: flex; align-items: flex-start; gap: 10px;
    padding: 12px 14px; border: 1px solid var(--color-neutral-line); border-radius: var(--radius-2xl);
    background: var(--color-neutral-soft); color: var(--color-text-secondary);
    font-size: var(--text-xs); line-height: 1.75;
  }
  .alert > i:first-child, .alert-icon { flex: none; margin-top: 3px; font-size: var(--text-sm); color: var(--color-neutral); }
  .alert-title { font-weight: 600; color: var(--color-text-primary); }
  .alert-info    { background: var(--color-accent-soft);  border-color: var(--color-accent-line); }
  .alert-info > i:first-child, .alert-info .alert-icon { color: var(--color-accent); }
  .alert-success { background: var(--color-success-soft); border-color: var(--color-success-line); }
  .alert-success > i:first-child, .alert-success .alert-icon { color: var(--color-success); }
  .alert-warning { background: var(--color-warning-soft); border-color: var(--color-warning-line); }
  .alert-warning > i:first-child, .alert-warning .alert-icon { color: var(--color-warning); }
  .alert-danger  { background: var(--color-danger-soft);  border-color: var(--color-danger-line); }
  .alert-danger > i:first-child, .alert-danger .alert-icon { color: var(--color-danger); }
  .alert-danger .alert-title { color: var(--color-danger-strong); }

  /* ── Icon tile & avatar ────────────────────────────────────────────────────────────────────
     Neutral by default. A tile takes a tone ONLY when the colour carries meaning (a status) —
     a row of KPI cards in four unrelated pastels is decoration, and it reads as a template. */
  .icon-tile {
    display: inline-flex; align-items: center; justify-content: center; flex: none;
    width: 36px; height: 36px; border-radius: var(--radius-xl);
    background: var(--color-bg-tertiary); color: var(--color-text-secondary); font-size: var(--text-sm);
  }
  .icon-tile-sm { width: 28px; height: 28px; border-radius: var(--radius-lg); font-size: var(--text-2xs); }
  .icon-tile-lg { width: 44px; height: 44px; border-radius: var(--radius-2xl); font-size: var(--text-md); }
  .icon-tile-primary { background: var(--color-primary); color: var(--color-on-primary); }
  .icon-tile-accent  { background: var(--color-accent-soft);  color: var(--color-accent-strong); }
  .icon-tile-success { background: var(--color-success-soft); color: var(--color-success-strong); }
  .icon-tile-warning { background: var(--color-warning-soft); color: var(--color-warning-strong); }
  .icon-tile-danger  { background: var(--color-danger-soft);  color: var(--color-danger-strong); }

  .avatar {
    display: inline-flex; align-items: center; justify-content: center; flex: none;
    width: 32px; height: 32px; border-radius: 9999px;
    background: var(--color-bg-tertiary); color: var(--color-text-secondary);
    font-size: var(--text-xs); font-weight: 600; line-height: 1;
  }
  .avatar-sm { width: 28px; height: 28px; font-size: var(--text-2xs); }
  .avatar-lg { width: 40px; height: 40px; font-size: var(--text-sm); }

  /* ── Stat (KPI) ────────────────────────────────────────────────────────────────────────────── */
  .stat-label { display: flex; align-items: center; gap: 6px; font-size: var(--text-xs); line-height: 1.5; color: var(--color-text-muted); }
  .stat-value { font-size: var(--text-2xl); line-height: 1.25; font-weight: 700; color: var(--color-text-primary); white-space: nowrap; }
  .stat-value-sm { font-size: var(--text-xl); }
  .stat-meta { font-size: var(--text-2xs); line-height: 1.6; color: var(--color-text-muted); }

  /* ── Progress / meter ──────────────────────────────────────────────────────────────────────── */
  .progress { position: relative; height: 6px; overflow: hidden; border-radius: 9999px; background: var(--color-bg-tertiary); }
  .progress-bar { height: 100%; border-radius: inherit; background: var(--color-primary); transition: width var(--duration-slow) var(--ease-standard); }

  /* ── Tabs ──────────────────────────────────────────────────────────────────────────────────
     .tabs      — page-level navigation between views (underline).
     .segmented — a compact switch between modes of ONE view (range pickers, toggles). */
  .tabs {
    display: flex; align-items: flex-end; gap: 4px; overflow-x: auto;
    border-bottom: 1px solid var(--color-border-light);
    scrollbar-width: none;
  }
  .tabs::-webkit-scrollbar { display: none; }
  .tab {
    position: relative; display: inline-flex; align-items: center; gap: 8px;
    height: 40px; padding-inline: 12px; margin-bottom: -1px;
    border-bottom: 2px solid transparent;
    font-size: var(--text-sm); font-weight: 500; color: var(--color-text-muted); white-space: nowrap; text-decoration: none;
    transition: color var(--duration-fast) var(--ease-standard), border-color var(--duration-fast) var(--ease-standard);
  }
  .tab:hover { color: var(--color-text-primary); }
  .tab.is-active, .tab[aria-current='page'], .tab[aria-selected='true'] { color: var(--color-text-primary); border-bottom-color: var(--color-primary); font-weight: 600; }
  .tab-count { display: inline-flex; align-items: center; height: 18px; padding-inline: 6px; border-radius: 9999px; background: var(--color-bg-tertiary); color: var(--color-text-secondary); font-size: var(--text-3xs); font-weight: 500; }

  .segmented {
    display: inline-flex; align-items: center; gap: 2px; padding: 3px;
    border-radius: var(--radius-xl); background: var(--color-bg-tertiary);
  }
  .segmented-item {
    display: inline-flex; align-items: center; justify-content: center; gap: 6px;
    height: 28px; padding-inline: 12px; border-radius: var(--radius-lg);
    font-size: var(--text-xs); font-weight: 500; color: var(--color-text-secondary); white-space: nowrap; text-decoration: none;
    transition: background-color var(--duration-fast) var(--ease-standard), color var(--duration-fast) var(--ease-standard);
  }
  .segmented-item:hover { color: var(--color-text-primary); }
  .segmented-item.is-active, .segmented-item[aria-current='page'], .segmented-item[aria-pressed='true'], .segmented-item[aria-selected='true'] {
    background: var(--color-bg-primary); color: var(--color-text-primary); font-weight: 600; box-shadow: var(--shadow-sm);
  }

  /* ── Data table ────────────────────────────────────────────────────────────────────────────── */
  .data-table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
  .data-table th {
    padding: 10px 16px; text-align: right; white-space: nowrap;
    background: var(--color-bg-secondary); border-bottom: 1px solid var(--color-border-light);
    font-size: var(--text-2xs); font-weight: 500; color: var(--color-text-muted);
  }
  .data-table td { padding: 12px 16px; vertical-align: middle; color: var(--color-text-primary); border-top: 1px solid var(--color-border-light); }
  .data-table tbody tr:first-child td { border-top: 0; }
  .data-table tbody tr { transition: background-color var(--duration-fast) var(--ease-standard); }
  .data-table tbody tr:hover { background: var(--color-bg-secondary); }
  .data-table .cell-muted { color: var(--color-text-muted); }
  .data-table .cell-num { white-space: nowrap; }
  .data-table th:first-child, .data-table td:first-child { padding-inline-start: 20px; }
  .data-table th:last-child, .data-table td:last-child { padding-inline-end: 20px; }

  /* ── Empty state ───────────────────────────────────────────────────────────────────────────── */
  .empty-state { display: flex; flex-direction: column; align-items: center; padding: 48px 24px; text-align: center; }
  .empty-state-icon {
    display: inline-flex; align-items: center; justify-content: center; width: 48px; height: 48px; margin-bottom: 16px;
    border-radius: var(--radius-2xl); border: 1px solid var(--color-border-light);
    background: var(--color-bg-secondary); color: var(--color-text-muted); font-size: var(--text-lg);
  }
  .empty-state-title { font-size: var(--text-base); font-weight: 600; line-height: 1.5; color: var(--color-text-primary); }
  .empty-state-text { margin-top: 4px; max-width: 28rem; font-size: var(--text-xs); line-height: 1.75; color: var(--color-text-muted); }
  .empty-state-actions { margin-top: 20px; display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }

  /* ── Menu / popover ────────────────────────────────────────────────────────────────────────── */
  .menu {
    min-width: 11rem; padding: 4px;
    border: 1px solid var(--color-border-light); border-radius: var(--radius-2xl);
    background: var(--color-bg-primary); box-shadow: var(--shadow-popover);
  }
  .menu-item {
    display: flex; width: 100%; align-items: center; gap: 10px; height: 34px; padding-inline: 10px;
    border-radius: var(--radius-lg); background: none; border: 0;
    font-family: inherit; font-size: var(--text-xs); color: var(--color-text-secondary); text-align: start; text-decoration: none; white-space: nowrap;
  }
  .menu-item > i { width: 16px; text-align: center; font-size: var(--text-2xs); color: var(--color-text-muted); }
  .menu-item:hover { background: var(--color-bg-secondary); color: var(--color-text-primary); }
  .menu-item-danger:hover, .menu-item-danger:hover > i { background: var(--color-danger-soft); color: var(--color-danger-strong); }
  .menu-divider { height: 1px; margin: 4px 0; background: var(--color-border-light); }
  /* A rich item: a title and one line of what it does, for a menu of ways to do one thing. */
  .menu-item-rich { height: auto; align-items: flex-start; gap: 12px; padding: 10px 12px; white-space: normal; cursor: pointer; }
  .menu-item-rich > i { margin-top: 4px; font-size: var(--text-xs); }
  .menu-item-body { display: flex; min-width: 0; flex-direction: column; gap: 2px; }
  .menu-item-title { font-size: var(--text-sm); font-weight: 500; line-height: 1.5; color: var(--color-text-primary); }
  .menu-item-hint { font-size: var(--text-2xs); line-height: 1.6; color: var(--color-text-muted); }
  .menu-item[aria-disabled='true'] { cursor: not-allowed; opacity: 0.55; }
  .menu-item[aria-disabled='true']:hover { background: none; }
  .menu-item:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
  /* The page header's menu action (shared/components/page-header): under its button, towards the
     page: the start edge on a phone, where the action sits on its own line; the end edge from sm. */
  .page-menu { position: relative; }
  .page-menu-panel { position: absolute; top: calc(100% + 6px); inset-inline-start: 0; z-index: var(--z-popover); width: min(23rem, calc(100vw - 2rem)); }
  @media (min-width: 640px) { .page-menu-panel { inset-inline-start: auto; inset-inline-end: 0; } }
  .btn-caret { font-size: var(--text-3xs); opacity: 0.8; }

  /* ── Dialog ────────────────────────────────────────────────────────────────────────────────
     Native <dialog class="kit-dialog dlg-*"> holding ONE `.kit-modal`. The modal is a flex
     column capped at the dialog's height, so the body scrolls and the header and footer stay. */
  .kit-dialog { border: none; background: transparent; color: inherit; padding: 0; overflow: visible; }
  .kit-dialog[open] { position: fixed; inset: 0; margin: auto; width: min(92vw, 30rem); height: fit-content; max-height: 88vh; }
  .kit-dialog.dlg-xs[open] { width: min(92vw, 26rem); max-height: 80vh; }
  .kit-dialog.dlg-sm[open] { width: min(92vw, 36rem); max-height: 80vh; }
  .kit-dialog.dlg-md[open] { width: min(92vw, 46rem); max-height: 84vh; }
  .kit-dialog.dlg-lg[open] { width: min(94vw, 60rem); max-height: 86vh; }
  .kit-dialog.dlg-xl[open] { width: min(96vw, 76rem); max-height: 90vh; }
  @media (max-width: 640px) {
    .kit-dialog[open] { width: calc(100vw - 24px) !important; max-height: 90vh !important; }
  }
  .kit-dialog::backdrop { background: var(--color-overlay); backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px); }
  .kit-modal {
    display: flex; flex-direction: column; max-height: inherit; overflow: hidden;
    background: var(--color-bg-primary); border: 1px solid var(--color-border-light);
    border-radius: var(--radius-dialog); box-shadow: var(--shadow-lg);
  }
  .kit-modal:focus, .kit-modal:focus-visible { outline: none; box-shadow: var(--shadow-lg); }
  .kit-modal-body, .modal-body { overflow-y: auto; }
  .modal-header {
    display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; flex: none;
    padding: 16px 20px; border-bottom: 1px solid var(--color-border-light);
  }
  .modal-title { font-size: var(--text-md); line-height: 1.5; font-weight: 600; color: var(--color-text-primary); }
  .modal-subtitle { margin-top: 2px; font-size: var(--text-xs); line-height: 1.65; color: var(--color-text-muted); }
  .modal-body { padding: 20px; }
  .modal-footer {
    display: flex; align-items: center; justify-content: flex-end; gap: 8px; flex: none;
    padding: 12px 20px; border-top: 1px solid var(--color-border-light); background: var(--color-bg-secondary);
  }
  .modal-close {
    display: inline-flex; align-items: center; justify-content: center; flex: none; width: 32px; height: 32px; margin: -4px;
    border-radius: var(--radius-lg); border: 0; background: none; color: var(--color-text-muted);
  }
  .modal-close:hover { background: var(--color-bg-tertiary); color: var(--color-text-primary); }

  /* ── App shell: sidebar navigation (shared by both panels) ─────────────────────────────────── */
  .app-sidebar {
    position: fixed; inset-block: 0; right: 0; z-index: var(--z-drawer);
    display: flex; flex-direction: column; width: var(--sidebar-w);
    background: var(--color-bg-primary); border-left: 1px solid var(--color-border-light);
    transition: transform var(--duration-slow) var(--ease-standard);
  }
  .app-sidebar-brand { display: flex; align-items: center; gap: 12px; height: 64px; flex: none; padding-inline: 16px; border-bottom: 1px solid var(--color-border-light); }
  .app-sidebar-mark {
    display: inline-flex; align-items: center; justify-content: center; flex: none; width: 34px; height: 34px;
    border-radius: var(--radius-xl); background: var(--color-primary); color: var(--color-on-primary);
    font-size: var(--text-sm); font-weight: 700;
  }
  .app-main { min-height: 100vh; padding: 16px; }
  @media (min-width: 1024px) { .app-main { margin-right: var(--sidebar-w); padding: 32px 40px; } }
  .app-topbar {
    position: sticky; top: 0; z-index: var(--z-sticky);
    display: flex; align-items: center; justify-content: space-between; height: 56px; padding-inline: 12px;
    background: var(--color-bg-primary); border-bottom: 1px solid var(--color-border-light);
  }

  .nav-section { padding: 16px 12px 6px; font-size: var(--text-3xs); font-weight: 600; color: var(--color-text-disabled); }
  .nav-item {
    display: flex; align-items: center; gap: 10px; height: 36px; padding-inline: 10px;
    border-radius: var(--radius-lg);
    font-size: var(--text-sm); font-weight: 500; color: var(--color-text-secondary); text-decoration: none;
    transition: background-color var(--duration-fast) var(--ease-standard), color var(--duration-fast) var(--ease-standard);
  }
  .nav-item > i { width: 18px; text-align: center; font-size: var(--text-xs); color: var(--color-text-muted); transition: color var(--duration-fast) var(--ease-standard); }
  .nav-item:hover { background: var(--color-bg-secondary); color: var(--color-text-primary); }
  .nav-item:hover > i { color: var(--color-text-secondary); }
  .nav-item.is-active { background: var(--color-bg-tertiary); color: var(--color-text-primary); font-weight: 600; }
  .nav-item.is-active > i { color: var(--color-text-primary); }
  .nav-item.is-disabled { color: var(--color-text-disabled); cursor: not-allowed; }
  .nav-item.is-disabled > i { color: var(--color-text-disabled); }
  .nav-item.is-tour { background: var(--color-primary); color: var(--color-on-primary); box-shadow: var(--shadow-md), 0 0 0 2px var(--color-white); }
  .nav-item.is-tour > i { color: var(--color-on-primary); }
  .nav-sub { margin-inline-start: 18px; padding-inline-start: 10px; border-inline-start: 1px solid var(--color-border-light); }
  .nav-sub .nav-item { height: 34px; font-size: var(--text-xs); }
  .nav-tag { margin-inline-start: auto; display: inline-flex; align-items: center; height: 18px; padding-inline: 6px; border-radius: 9999px; background: var(--color-bg-tertiary); color: var(--color-text-muted); font-size: var(--text-3xs); font-weight: 500; }
  .nav-item.is-tour .nav-tag { background: var(--color-white); color: var(--color-primary); font-weight: 700; }

  /* ── Filter bar (shared/components/filter-bar.ejs) ─────────────────────────────────────────
     ONE height for every control in the toolbar, the popover, the mobile sheet and the wizard
     panel. Box metrics only, so nothing fights a `w-*` utility. */
  .fbar-ctl {
    box-sizing: border-box; width: 100%; height: var(--control-h-sm); min-height: 0; padding: 0 12px;
    border: 1px solid var(--color-border-medium); border-radius: var(--radius-lg);
    background: var(--color-bg-primary); color: var(--color-text-primary);
    font-size: var(--text-xs); line-height: 1; box-shadow: var(--shadow-xs);
  }
  .fbar-ctl:hover { border-color: var(--color-border-dark); }
  .fbar-ctl:focus { border-color: var(--color-accent); box-shadow: var(--shadow-focus); }
  .fbar-ctl::placeholder { color: var(--color-text-disabled); }
  .fbar-ctl--search { padding-right: 30px; }
  .fbar-ctl--search::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }
  .fbar-ctl--select { -webkit-appearance: none; -moz-appearance: none; appearance: none; padding-left: 26px; color: var(--color-text-secondary); }
  .fbar-ctl--select::-ms-expand { display: none; }
  .fbar-ctl--date { -webkit-appearance: none; appearance: none; padding: 0 8px; }
  .fbar-ctl--date::-webkit-datetime-edit { padding: 0; }
  .fbar-ctl--date::-webkit-datetime-edit-fields-wrapper { padding: 0; }
  .fbar-ctl--date::-webkit-calendar-picker-indicator { margin: 0; padding: 0; opacity: 0.5; cursor: pointer; }
  .fbar-ctl--date::-webkit-inner-spin-button { display: none; }
  .fbar-btn {
    display: inline-flex; align-items: center; gap: 6px; box-sizing: border-box;
    height: var(--control-h-sm); min-height: 0; border-radius: var(--radius-lg);
    font-size: var(--text-xs); font-weight: 600; line-height: 1; white-space: nowrap;
    transition: background-color var(--duration-fast) var(--ease-standard), border-color var(--duration-fast) var(--ease-standard);
  }
  .fbar-btn--primary { background: var(--color-primary); color: var(--color-on-primary); box-shadow: var(--shadow-button); }
  .fbar-btn--primary:hover { background: var(--color-primary-hover); }
  .fbar-btn--ghost { background: var(--color-bg-primary); color: var(--color-text-primary); border: 1px solid var(--color-border-medium); box-shadow: var(--shadow-xs); }
  .fbar-btn--ghost:hover { background: var(--color-bg-secondary); border-color: var(--color-border-dark); }
  .fbar-badge {
    position: absolute; top: -5px; left: -5px; min-width: 16px; height: 16px; padding: 0 4px;
    display: inline-flex; align-items: center; justify-content: center; border-radius: 9999px;
    background: var(--color-accent); color: var(--color-white);
    font-size: var(--text-3xs); font-weight: 700; line-height: 1;
  }
  .fbar-meta {
    display: inline-flex; align-items: center; height: var(--control-h-sm); padding: 0 10px;
    border-radius: 9999px; background: var(--color-bg-tertiary); color: var(--color-text-secondary);
    font-size: var(--text-2xs); white-space: nowrap;
  }

  /* ── Range slider ──────────────────────────────────────────────────────────────────────────── */
  .kit-range { -webkit-appearance: none; appearance: none; width: 100%; height: 6px; border-radius: 9999px; background: var(--color-bg-tertiary); }
  .kit-range::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 18px; height: 18px; border-radius: 9999px; background: var(--color-primary); border: 3px solid var(--color-white); box-shadow: var(--shadow-sm); cursor: pointer; margin-top: -6px; transition: transform var(--duration-fast) ease; }
  .kit-range::-webkit-slider-thumb:hover { transform: scale(1.1); }
  .kit-range::-moz-range-thumb { width: 18px; height: 18px; border-radius: 9999px; background: var(--color-primary); border: 3px solid var(--color-white); box-shadow: var(--shadow-sm); cursor: pointer; }
  .kit-range::-moz-range-track { height: 6px; border-radius: 9999px; background: var(--color-bg-tertiary); }
  .kit-range:focus-visible::-webkit-slider-thumb { box-shadow: var(--shadow-focus); }
  .kit-range:focus-visible::-moz-range-thumb { box-shadow: var(--shadow-focus); }

  /* ── Loading (also injected by uikit.js for pages without this file) ──────────────────────── */
  @keyframes uikit-spin { to { transform: rotate(360deg); } }
  .kit-spin { display: inline-block !important; animation: uikit-spin 0.7s linear infinite !important; transform-origin: center; will-change: transform; }
  .kit-spinner { display: inline-block; box-sizing: border-box; width: 1em; height: 1em; vertical-align: -0.125em; border: 2px solid currentColor; border-right-color: transparent; border-radius: 9999px; animation: uikit-spin 0.6s linear infinite; will-change: transform; }
  [data-spinner] { display: none; }
  .is-loading { pointer-events: none; opacity: 0.75; }
  .is-loading [data-spinner] { display: inline-block; }
  .is-loading [data-icon] { display: none; }
  .skeleton { border-radius: var(--radius-md); background: linear-gradient(90deg, var(--color-bg-tertiary) 0%, var(--color-bg-secondary) 50%, var(--color-bg-tertiary) 100%); background-size: 200% 100%; animation: skeleton 1.4s ease-in-out infinite; }
  @keyframes skeleton { from { background-position: 200% 0; } to { background-position: -200% 0; } }

  /* ── Domain components ─────────────────────────────────────────────────────────────────────
     Components that belong to one area of the product but are still shared by several of its
     screens. Generic first: reach for the components above before adding one here. */
  /* [area:dashboard-lists] */
  /* Tag chip — one of the tenant's own tags (dashboard, leads, lead detail, tags page). A
     neutral pill: the tag's colour is the tenant's CONTENT, not a theme value, so it reaches
     only the icon, through `style="--tag-color: …"`. Many tags side by side then read as one
     calm list with coloured markers, not as a rainbow of pastel fills. */
  .tag-chip {
    display: inline-flex; align-items: center; gap: 6px; box-sizing: border-box; max-width: 100%;
    height: 24px; padding-inline: 8px; border-radius: 9999px;
    border: 1px solid var(--color-border-medium); background: var(--color-bg-primary);
    color: var(--color-text-secondary); font-size: var(--text-2xs); font-weight: 500; line-height: 1; white-space: nowrap;
  }
  .tag-chip > i { flex: none; font-size: 0.9em; color: var(--tag-color, var(--color-text-muted)); }
  .tag-chip-count { color: var(--color-text-muted); font-weight: 400; }
  .tag-chip-lg { height: 28px; padding-inline: 10px; font-size: var(--text-xs); }
  a.tag-chip { transition: border-color var(--duration-fast) var(--ease-standard), color var(--duration-fast) var(--ease-standard); }
  a.tag-chip:hover { border-color: var(--color-border-dark); color: var(--color-text-primary); }

  /* Tag toggle — a tag chip you can switch on and off (the lead edit form). The checkbox is the
     control, laid invisibly over the chip so the whole chip is the hit area and the keyboard and
     screen readers get a real checkbox. On is the accent: it means «selected», not a status. */
  .tag-toggle { position: relative; display: inline-flex; max-width: 100%; cursor: pointer; }
  .tag-toggle > input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
  .tag-toggle > .tag-chip { transition: border-color var(--duration-fast) var(--ease-standard), background-color var(--duration-fast) var(--ease-standard), color var(--duration-fast) var(--ease-standard); }
  .tag-toggle:hover > .tag-chip { border-color: var(--color-border-dark); }
  .tag-toggle > input:checked + .tag-chip { border-color: var(--color-accent-line); background: var(--color-accent-soft); color: var(--color-accent-strong); }
  .tag-toggle > input:focus-visible + .tag-chip { box-shadow: var(--shadow-focus); }

  /* Sparkline — server-rendered SVG under a KPI value. One series, so one colour: the accent.
     The path is drawn in a fixed viewBox and stretched to the card's width; the stroke keeps
     its own width while it stretches. */
  .spark { display: block; width: 100%; height: 36px; overflow: visible; }
  .spark-line { fill: none; stroke: var(--color-accent); stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
  .spark-area { fill: var(--color-accent); opacity: 0.08; }

  /* Distribution bar — one 100% bar split into ordered segments (a share of a whole), with a
     2px surface gap between them. Segment colours come from the sequential ramp (bg-seq-N). */
  .dist-bar { display: flex; height: 10px; overflow: hidden; border-radius: 9999px; background: var(--color-bg-tertiary); }
  .dist-bar > span { height: 100%; min-width: 0; }
  .dist-bar > span + span { border-inline-start: 2px solid var(--color-bg-primary); }
  .legend-dot { display: inline-block; flex: none; width: 8px; height: 8px; border-radius: 9999px; }
  /* [area:settings] */
  /* [area:hooks] */
  /* [area:owner-panel] */
  /* [area:public-shared] */

  /* ── Public pages ── the hook landing, its delivery, the opt-out page and a visitor's error
     page: one narrow column on the canvas, the workshop's mark, one card, a quiet footer.

     The tenant's brand colour is CONTENT, not a theme value. site/components/_brand-style.ejs
     writes it as --brand (+ -soft, -line) and lends it to `.btn-primary` inside `.public-page`;
     without a brand the product's ink stays. Every palette entry clears AA against white, so
     the label on a brand fill is always --color-on-primary.

     Top-aligned on purpose: the form, the code step and the delivery start at the same height,
     so the page never jumps between steps and a phone keyboard never pushes the field away. */
  .public-page {
    display: flex; flex-direction: column; align-items: center;
    min-height: 100vh; min-height: 100dvh; padding: 28px 16px 20px;
  }
  @media (min-width: 640px) { .public-page { padding-top: 56px; } }
  .public-shell { display: flex; flex-direction: column; flex: 1 0 auto; width: 100%; max-width: 440px; }
  .public-shell-wide { max-width: 720px; }

  .public-brand { display: flex; align-items: center; justify-content: center; gap: 10px; min-width: 0; margin-bottom: 20px; }
  .public-brand-name { min-width: 0; font-size: var(--text-sm); line-height: var(--text-sm--line-height); font-weight: 600; color: var(--color-text-primary); overflow-wrap: anywhere; }
  /* The workshop's mark: its logo as drawn (no plate, no frame, never cropped, at the height of
     the initial it replaces), or its initial on its brand colour. `multiply` lets a JPEG logo's
     own white background disappear into the canvas instead of showing as a white box. */
  .brand-mark {
    flex: none; display: inline-flex; align-items: center; justify-content: center;
    width: 32px; height: 32px; border-radius: var(--radius-lg);
    background: var(--brand, var(--color-primary)); color: var(--color-on-primary);
    font-size: var(--text-sm); font-weight: 700; line-height: 1;
  }
  img.brand-mark { width: auto; max-width: 132px; height: 28px; border-radius: 0; object-fit: contain; background: none; mix-blend-mode: multiply; }
  .brand-mark-lg { width: 56px; height: 56px; border-radius: var(--radius-2xl); font-size: var(--text-xl); }
  img.brand-mark-lg { width: auto; max-width: 200px; height: 48px; }

  .public-cover { display: block; width: 100%; aspect-ratio: 16 / 9; object-fit: cover; border-bottom: 1px solid var(--color-border-light); }
  .public-body { display: flex; flex-direction: column; gap: 24px; padding: 28px; }
  @media (max-width: 639px) { .public-body { padding: 24px 20px; } }
  .public-head { text-align: center; }
  .public-head > .icon-tile { margin: 0 auto 16px; }
  .public-title { font-size: var(--text-xl); line-height: var(--text-xl--line-height); font-weight: 700; color: var(--color-text-primary); overflow-wrap: anywhere; }
  .public-lead { margin-top: 6px; font-size: var(--text-sm); line-height: 1.85; color: var(--color-text-secondary); white-space: pre-line; text-wrap: balance; }
  .public-note { display: flex; align-items: flex-start; justify-content: center; gap: 6px; font-size: var(--text-2xs); line-height: 1.7; color: var(--color-text-muted); text-align: center; text-wrap: balance; }
  .public-note > i { margin-top: 3px; color: var(--color-text-disabled); }
  .public-foot { margin-top: auto; padding-top: 28px; text-align: center; font-size: var(--text-2xs); line-height: 1.6; color: var(--color-text-muted); }
  .public-actions { display: flex; align-items: center; justify-content: space-between; gap: 12px; font-size: var(--text-xs); color: var(--color-text-muted); }
  .public-actions .btn-link { font-size: var(--text-xs); }

  /* 16px text in every public control: anything smaller makes iOS zoom the page on focus. */
  .input-lg { height: var(--control-h-lg); font-size: var(--text-md); }
  textarea.input-lg { height: auto; padding-block: 10px; }
  /* The one-time code: big, centred, spaced, and always left to right. The inline-start padding
     balances the letter-spacing that trails the last digit, so the code sits truly centred. */
  .input-code {
    height: 56px; direction: ltr; text-align: center;
    font-size: var(--text-2xl); font-weight: 600; letter-spacing: 0.4em; padding-inline-start: calc(12px + 0.4em);
  }
  .input-code::placeholder { letter-spacing: 0.4em; color: var(--color-border-medium); }

  /* What a delivery hands over. A file: its type, its name, its size, on one quiet row. */
  .public-file { display: flex; align-items: center; gap: 12px; min-width: 0; }
  .public-file > .icon-tile { flex: none; }
  .public-file-name { min-width: 0; font-size: var(--text-sm); font-weight: 600; color: var(--color-text-primary); overflow-wrap: anywhere; direction: ltr; text-align: right; unicode-bidi: plaintext; }
  .public-file-meta { margin-top: 2px; font-size: var(--text-2xs); color: var(--color-text-muted); }
  .public-video { display: block; width: 100%; aspect-ratio: 16 / 9; border-radius: var(--radius-2xl); background: var(--color-black); }
  /* A mini-course session: its number and title above its player. */
  .public-session { overflow: hidden; border: 1px solid var(--color-border-light); border-radius: var(--radius-2xl); }
  .public-session-head { display: flex; align-items: center; gap: 10px; padding: 10px 14px; border-bottom: 1px solid var(--color-border-light); background: var(--color-bg-secondary); font-size: var(--text-sm); font-weight: 500; color: var(--color-text-primary); }
  .public-session .public-video { border-radius: 0; }
  /* An attachment: a whole-row link to save one file. */
  .public-resource {
    display: flex; align-items: center; gap: 12px; padding: 12px 14px;
    border: 1px solid var(--color-border-medium); border-radius: var(--radius-control);
    background: var(--color-bg-primary); color: var(--color-text-primary); font-size: var(--text-sm); text-decoration: none;
    box-shadow: var(--shadow-xs);
    transition: border-color var(--duration-fast) var(--ease-standard), background-color var(--duration-fast) var(--ease-standard);
  }
  .public-resource:hover { border-color: var(--color-border-dark); background: var(--color-bg-secondary); }
  .public-resource > i { color: var(--color-text-muted); }
  .public-resource > span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

  /* The page a tracked link shows for an instant (site/pages/links/tap.ejs, offers/click-confirm):
     the browser confirms the tap and leaves for the destination. It loads only tokens, the face
     and this file, never the Tailwind runtime, so its layout lives here. The status line belongs
     to the script: `.js` is set on <html> by the page's first script, and without it only the
     button is offered. Without Tailwind's preflight the body keeps the browser's own margin, which
     on top of `body { min-height: 100vh }` scrolls the page by 16px, so `.tap-body` takes it off. */
  .tap-body { margin: 0; }
  .tap-page { display: flex; justify-content: center; align-items: flex-start; padding: 40px 16px; box-sizing: border-box; }
  .tap-card { display: flex; flex-direction: column; gap: 16px; width: 100%; max-width: 400px; text-align: center; }
  .tap-brand { margin: 0; font-size: var(--text-md); line-height: var(--text-md--line-height); font-weight: 700; color: var(--color-text-primary); overflow-wrap: anywhere; }
  .tap-status { display: none; align-items: center; justify-content: center; gap: 8px; margin: 0; color: var(--color-text-secondary); }
  .js .tap-status { display: flex; }
  .tap-note { margin: 0; font-size: var(--text-xs); line-height: var(--text-xs--line-height); color: var(--color-text-muted); }
  @media (min-width: 640px) { .tap-page { padding-top: 64px; } }
  /* [area:standalone] */
}
