/* ═══════════════════════════════════════════════
   DASHBOARD — app shell (sidebar + topbar + pages)
   Loads after style.css and reuses its tokens.
   ═══════════════════════════════════════════════ */

/* ⭐ REDESIGN STEP 3, area 1 (2026-09-16): the shell takes the landing page's look — a LIGHT
   sidebar (user's decision 2, 2026-09-16: "go for new look", not navy), a white translucent top
   bar, the display face for titles, pill buttons, and the landing page's pale page ground. */
.dash-body { background: var(--grey-50); }

.dash-app {
  display: flex;
  min-height: 100vh;
}

/* ── Sidebar ── */
.dash-sidebar {
  width: 244px;
  flex-shrink: 0;
  background: var(--white);
  border-right: 1px solid var(--grey-200);
  color: var(--grey-800);
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
}

.dash-logo {
  display: block;
  padding: 22px 22px 18px;
  color: var(--grey-900);
  text-decoration: none;
  font-family: var(--display);
  font-size: 1.3rem;
  font-weight: 400;
  letter-spacing: -0.01em;
}
.dash-logo strong { font-weight: 800; }

.dash-nav {
  flex: 1;
  padding: 6px 12px 14px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.dash-nav-item {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 9px 12px;
  border-radius: 10px;
  color: var(--grey-700);
  text-decoration: none;
  font-size: 0.9rem;
  font-weight: 500;
  transition: background 0.15s, color 0.15s;
}
.dash-nav-item:hover { background: var(--grey-100); color: var(--grey-900); }
/* The current page: a pale brand pill with brand text — not a filled block, which on a
   white sidebar would shout louder than the page it belongs to. */
.dash-nav-item.active { background: var(--eu-blue-light); color: var(--eu-blue); font-weight: 600; }

/* Line icons (Lucide, ISC licence — the same family as the Workflow tiles) replaced the old
   Unicode symbols (⌂ ▤ ☰ ▦ …), which rendered at different sizes and weights per font. */
.dash-nav-icon {
  width: 20px;
  height: 20px;
  flex: none;
  display: grid;
  place-items: center;
  color: var(--grey-500);
}
.dash-nav-icon svg { width: 18px; height: 18px; }
.dash-nav-item:hover .dash-nav-icon { color: var(--grey-800); }
.dash-nav-item.active .dash-nav-icon { color: var(--eu-blue); }

.dash-sidebar-foot {
  padding: 14px 22px;
  border-top: 1px solid var(--grey-200);
  font-size: 0.8rem;
}

.dash-plan-badge {
  display: inline-block;
  padding: 4px 11px;
  border-radius: 999px;
  background: var(--grey-100);
  color: var(--grey-700);
  font-family: var(--mono);
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-size: 0.72rem;
}

/* ── Main column ── */
.dash-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.dash-topbar {
  background: rgba(255, 255, 255, 0.88);
  backdrop-filter: saturate(1.4) blur(10px);
  -webkit-backdrop-filter: saturate(1.4) blur(10px);
  border-bottom: 1px solid var(--grey-200);
  min-height: 64px;
  box-sizing: border-box;
  padding: 10px 28px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  position: sticky;
  top: 0;
  z-index: 20;
}

.dash-topbar-title {
  font-family: var(--display);
  font-size: 1.2rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--grey-900);
  margin: 0;
  line-height: inherit;
}

.dash-topbar-user {
  display: flex;
  align-items: center;
  gap: 12px;
}

.dash-topbar-userinfo {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  line-height: 1.2;
}
.dash-topbar-org {
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--grey-700);
}
.dash-user-email {
  font-size: 0.82rem;
  color: var(--grey-600);
}

/* A pill, like the landing page's quiet button. .btn-ghost (style.css) gives the base. */
.dash-signout {
  padding: 8px 16px;
  font-size: 0.85rem;
  font-weight: 600;
  border-radius: 999px;
  border: 1px solid var(--grey-200);
  background: var(--white);
  color: var(--grey-800);
}
.dash-signout:hover { border-color: var(--eu-blue); color: var(--eu-blue); background: var(--white); }

.dash-content {
  padding: 24px 28px 60px;
  max-width: 1040px;
  width: 100%;
  flex: 1 0 auto;   /* grow so the footer is pushed to the bottom */
}

/* ── Setup warning banner ── */
.dash-setup-warning {
  margin: 16px 28px 0;
  padding: 12px 16px;
  background: var(--risk-limited-bg);
  border: 1px solid var(--risk-limited-border);
  border-radius: 8px;
  color: var(--risk-limited);
  font-size: 0.9rem;
}
.dash-setup-warning code {
  background: rgba(0,0,0,0.06);
  padding: 1px 5px;
  border-radius: 4px;
  font-size: 0.8rem;
}

/* ── Dashboard notice banner ── */
/* My Account — scope tick-boxes, and the delete-account danger zone. */
.dash-account-hint {
  font-size: 0.8rem;
  color: var(--grey-600);
  line-height: 1.5;
  margin: 2px 0 10px;
  max-width: 640px;
}
/* Small "i" tooltip beside a field label. */
.info-ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 15px;
  height: 15px;
  margin-left: 6px;
  border-radius: 50%;
  background: var(--eu-blue);
  color: #fff;
  font-size: 0.66rem;
  font-weight: 700;
  font-style: italic;
  font-family: Georgia, 'Times New Roman', serif;
  cursor: help;
  vertical-align: middle;
}
.info-ico:hover, .info-ico:focus { background: var(--eu-blue-dark); color: #fff; outline: none; }

/* ── My Account, rearranged (user, 2026-09-17) ───────────────────────────────
   Two columns: the business card (the only thing with a Save button) on the left,
   and one small card per other job on the right, each acting on its own. One column
   below 1000px, where the right-hand cards would be too narrow to read. */
.acc-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
  gap: 20px;
  align-items: start;
}
.acc-main, .acc-side { display: flex; flex-direction: column; gap: 20px; min-width: 0; }
@media (max-width: 1000px) { .acc-grid { grid-template-columns: minmax(0, 1fr); } }

/* The business card saves along its foot: a bar the width of the card, saying what it
   saves on the left and the button on the right, so it cannot be read as a save for
   the whole page. The negative margins take it out to the card edge. */
.acc-savebar {
  display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap;
  gap: 10px 16px;
  margin: 22px -24px -22px;
  padding: 14px 24px;
  background: var(--grey-50);
  border-top: 1px solid var(--grey-200);
  border-radius: 0 0 16px 16px;
}
.acc-savebar-what { margin: 0; flex: 1 1 220px; font-size: 0.8rem; line-height: 1.5; color: var(--grey-600); }
.acc-savebar-do { display: flex; align-items: center; gap: 12px; flex: none; }
.acc-savebar .dash-account-saved { margin: 0; }
.acc-savebar .field-error { margin: 0; flex-basis: 100%; }

/* Delete account: a card of its own, edged in red rather than divided off by a rule. */
.dash-danger-zone { border-color: var(--risk-high-border); }
.dash-danger-title { color: var(--risk-high); }
/* "Danger zone" holds more than one removal (2026-10-10): each is a block with its own small heading. */
.dash-danger-item + .dash-danger-item { border-top: 1px solid var(--grey-100); margin-top: 18px; padding-top: 16px; }
.dash-danger-item.hidden + .dash-danger-item { border-top: 0; margin-top: 0; padding-top: 0; }
.dash-danger-sub { font-size: 0.92rem; font-weight: 700; color: var(--grey-900); margin: 0 0 4px; }

/* Topbar identity: page title · business name, with the organisation type. */
.dash-topbar-titlewrap {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  flex-wrap: wrap;
}
.dash-topbar-sep { color: var(--grey-400); font-weight: 400; }
.dash-topbar-sep.hidden { display: none; }
.dash-topbar-entity {
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--grey-600);
  background: var(--grey-100);
  border: 1px solid var(--grey-200);
  border-radius: 20px;
  padding: 2px 9px;
  white-space: nowrap;
}

/* Scope verdict, reusing the landing page's .scope-result block (style.css)
   so the dashboard restates what the customer was told before signing up.
   On the dashboard it is a slim one-line status stripe (not the big card the
   landing page shows) — informative but low-key, so it doesn't read as an error. */
.dash-scope-reminder {
  margin-bottom: 22px;
  padding: 10px 16px;
  align-items: center;
  gap: 10px;
  border-radius: 12px;
}
/* Two classes, to beat style.css's `.scope-result.applies` / `.unlikely` outlines. */
.dash-scope-reminder.scope-result { border: 0; }
.dash-scope-reminder .scope-result-icon { font-size: 1rem; }
.dash-scope-reminder .scope-result-title { margin-bottom: 0; font-size: 0.85rem; }
.dash-scope-reminder .scope-result-body { display: none; }
/* Read more (2026-09-21): the reasons open under the line. */
.dash-scope-reminder.open { align-items: flex-start; padding: 14px 16px; }
.dash-scope-reminder.open .scope-result-body { display: block; margin-top: 8px; font-size: 0.85rem; line-height: 1.55; }
.dash-scope-reminder .scope-result-body p { margin: 0 0 8px; }
.dash-scope-reminder > div:not(.scope-result-icon) { flex: 1; min-width: 0; }
.dash-scope-reminder .scope-close-btn { color: var(--grey-600); align-self: flex-start; }
.scope-more-btn {
  margin-left: 8px; padding: 0; background: none; border: none; font: inherit;
  font-weight: 600; color: var(--eu-blue); cursor: pointer; text-decoration: underline;
}
.scope-more-btn:hover { text-decoration: none; }

.dash-notice {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px 12px 16px;
  margin-bottom: 20px;
  background: var(--risk-limited-bg);
  border: 1px solid var(--risk-limited-border);
  border-radius: 12px;
  color: var(--risk-limited);
  font-size: 0.9rem;
}
.dash-notice.hidden { display: none; }
.dash-notice-icon { font-size: 1.1rem; flex-shrink: 0; }
.dash-notice-text { flex: 1; line-height: 1.5; }
.dash-notice-text a { color: var(--risk-limited); font-weight: 700; text-decoration: underline; }
.dash-notice-close {
  flex-shrink: 0;
  border: none;
  background: none;
  color: var(--risk-limited);
  font-size: 1rem;
  cursor: pointer;
  padding: 2px 6px;
  border-radius: 4px;
  opacity: 0.7;
}
.dash-notice-close:hover { opacity: 1; background: rgba(0,0,0,0.06); }

/* ── Process flow ── */
.dash-flow-title {
  font-family: var(--display);
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--grey-900);
  margin-bottom: 12px;
}

.dash-flow {
  display: flex;
  align-items: stretch;
  gap: 4px;
  margin-bottom: 24px;
  flex-wrap: nowrap;
}

.dash-flow-step {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 12px;
  padding: 24px 14px 18px;
  background: var(--white);
  border: 1px solid var(--grey-200);
  border-radius: 16px;
  box-shadow: 0 1px 2px rgba(11, 27, 63, 0.04);
  text-decoration: none;
  overflow: hidden;
  transition: transform 0.2s, box-shadow 0.2s, border-color 0.2s;
}
.dash-flow-step:hover {
  transform: translateY(-3px);
  border-color: transparent;
  box-shadow: var(--shadow-lg);
}

/* Each stage carries its own accent so the row reads as a coloured journey.
   Same four colours and gradient pairs as the landing page's step cards (site.css
   .lp-step), so the app and the site read as one product. */
.dash-flow-step:nth-of-type(1) { --accent: #3b5bdb; --accent-2: #5c7cfa; }
.dash-flow-step:nth-of-type(2) { --accent: #0ca678; --accent-2: #20c997; }
.dash-flow-step:nth-of-type(3) { --accent: #e8590c; --accent-2: #fd7e14; }
.dash-flow-step:nth-of-type(4) { --accent: #7048e8; --accent-2: #9775fa; }

.dash-flow-icon {
  width: 56px;
  height: 56px;
  border-radius: 16px;
  background: linear-gradient(140deg, var(--accent-2, var(--eu-blue)), var(--accent, var(--eu-blue)));
  box-shadow: 0 10px 22px -12px var(--accent, var(--eu-blue)), inset 0 1px 0 rgba(255, 255, 255, 0.35);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
}
.dash-flow-icon svg { width: 28px; height: 28px; }

.dash-flow-label {
  font-family: var(--display);
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--grey-900);
  line-height: 1.3;
}

.dash-flow-stats {
  width: 100%;
  margin-top: 2px;
  padding-top: 12px;
  border-top: 1px solid var(--grey-200);
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.dash-flow-stat-main { font-family: var(--display); font-size: 1.2rem; font-weight: 700; color: var(--accent, var(--eu-blue-dark)); line-height: 1.2; }
.dash-flow-stat-sub { font-size: 0.8rem; color: var(--grey-700); }
.dash-flow-stat-date { font-size: 0.72rem; color: var(--grey-400); }
/* platform-side "last updated by AIcompliancy" line */
.dash-flow-sysdate {
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px dashed var(--grey-200);
  font-size: 0.72rem;
  color: var(--grey-500);
  line-height: 1.35;
}
.dash-flow-sysdate strong { color: var(--grey-600); font-weight: 700; }

.dash-flow-arrow {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--grey-400);
  flex-shrink: 0;
}
.dash-flow-arrow svg { width: 22px; height: 22px; }

@media (max-width: 720px) {
  .dash-flow { flex-direction: column; }
  /* ⛔ THE TITLE AND THE FIGURES WERE PRINTED ON TOP OF EACH OTHER (found 2026-09-18,
     first phone-width check). Turning the tile into a flex ROW left .dash-flow-stats
     with the `width: 100%` it needs as a COLUMN, so the figures claimed the whole
     tile and the title was squeezed behind them — "Create software li…" under
     "3 in catalogue · 1 manual", on all four tiles.
     A two-column grid instead: the icon down the left across both rows, the title on
     the first, the figures under it on the second. */
  .dash-flow-step {
    /* ⛔ AND THE TILES WERE 34px TALL, whatever was inside them. `flex: 1 1 0` sizes a
       tile across the ROW on a wide page; the moment .dash-flow turns into a column it
       starts sizing the HEIGHT from a basis of zero, so all four split the height
       equally and `overflow: hidden` cut off the rest. Back to content height here. */
    flex: 0 0 auto;
    display: grid;
    grid-template-columns: 44px minmax(0, 1fr);
    grid-template-areas: "icon label" "icon stats";
    column-gap: 14px;
    row-gap: 8px;
    align-items: center;
    text-align: left;
    padding: 16px 16px 16px 18px;
  }
  .dash-flow-icon { grid-area: icon; align-self: start; width: 44px; height: 44px; border-radius: 13px; }
  .dash-flow-icon svg { width: 24px; height: 24px; }
  .dash-flow-label { grid-area: label; }
  .dash-flow-stats { grid-area: stats; width: auto; margin-top: 0; padding-top: 10px; }
  .dash-flow-arrow { transform: rotate(90deg); }
}
/* ── Cards / stubs ── */
.dash-account-card { padding: 22px 24px; }

.dash-card-title {
  font-size: 1.15rem;
  color: var(--grey-900);
  margin-bottom: 10px;
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--display);
  letter-spacing: -0.01em;
}


/* ── Software Library ── */
/* overflow visible so the autocomplete dropdown isn't clipped by
   the card's overflow:hidden (used for its rounded corners). */
.dash-add-card { padding: 18px 20px; overflow: visible; }

.dash-add-row {
  display: flex;
  gap: 10px;
  align-items: center;
  flex-wrap: wrap;
}

.dash-add-input-wrap {
  position: relative;
  flex: 1;
  min-width: 220px;
}

/* ── Browse the catalogue (Library page) ──────────────────────────
   Auto-fit columns rather than a fixed count: three or four on a laptop, one on a
   phone, without a breakpoint to maintain. Capped in height so opening it does not
   push the library list off the screen. */
.lib-browse { margin-top: 16px; border-top: 1px solid var(--grey-200); padding-top: 14px; }
.lib-browse-head { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
/* No filter box of its own: the Add-software field above IS the filter while this
   panel is open, and two fields doing one job is what the user asked me to remove. */
.lib-browse-hint { flex: 1; min-width: 200px; font-size: 0.8rem; color: var(--grey-600); }
.lib-browse-count { font-size: 0.8rem; color: var(--grey-600); white-space: nowrap; }
.lib-browse-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(210px, 100%), 1fr));
  gap: 10px;
  margin-top: 12px;
  max-height: 46vh;
  overflow-y: auto;
  padding: 2px;   /* room for the hover border without clipping at the scroll edge */
}
.lib-pick {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px; text-align: left; cursor: pointer;
  background: var(--white); border: 1px solid var(--grey-200);
  border-radius: 12px; font: inherit; color: inherit;
  transition: border-color 0.15s, background 0.15s;
}
.lib-pick:hover { border-color: var(--eu-blue); background: var(--eu-blue-pale); }
.lib-pick.added { border-color: var(--eu-blue); background: var(--eu-blue-light); }
.lib-pick-mark {
  display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; flex: none; border-radius: 50%;
  background: var(--grey-100); color: var(--grey-600);
  font-size: 0.8rem; font-weight: 700; line-height: 1;
}
.lib-pick.added .lib-pick-mark { background: var(--eu-blue); color: #fff; }
.lib-pick-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.lib-pick-name { font-size: 0.85rem; font-weight: 600; color: var(--grey-900); }
.lib-pick-meta { font-size: 0.75rem; color: var(--grey-600); }
.lib-browse-none { font-size: 0.85rem; color: var(--grey-600); margin: 14px 2px; }
.lib-browse-foot { font-size: 0.8rem; color: var(--grey-600); margin: 12px 2px 0; }

/* ── Paste a list (Library page, 2026-10-04) ────────────────────────
   Same panel shape as Browse. Each row: a coloured dot + a written status (the colour
   is never the only signal), the name as typed, and what will be added for it.
   Green / amber / grey reuse the risk colours' shades only as dots, never as pills,
   so a match status cannot be read as a risk level. */
.lib-bulk { margin-top: 16px; border-top: 1px solid var(--grey-200); padding-top: 14px; }
.lib-bulk-hint { font-size: 0.85rem; color: var(--grey-700); margin: 0 2px 10px; line-height: 1.5; }
.lib-bulk-text { width: 100%; min-height: 130px; resize: vertical; font: inherit; }
.lib-bulk-actions { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; margin-top: 12px; }

.lib-bulk-chips { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
.lib-bulk-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px; border-radius: 999px; font-size: 0.8rem;
  background: var(--grey-50); border: 1px solid var(--grey-200); color: var(--grey-700);
}
.lib-bulk-dot { width: 9px; height: 9px; border-radius: 50%; flex: none; background: var(--grey-400); }
.lib-bulk-exact .lib-bulk-dot { background: var(--risk-minimal-border); }
.lib-bulk-close .lib-bulk-dot { background: var(--risk-limited-border); }
.lib-bulk-none  .lib-bulk-dot { background: var(--grey-400); }
.lib-bulk-have  .lib-bulk-dot { background: var(--eu-blue); }

.lib-bulk-list {
  border: 1px solid var(--grey-200); border-radius: 12px;
  max-height: 52vh; overflow-y: auto; background: var(--white);
}
.lib-bulk-row {
  display: grid; grid-template-columns: auto minmax(0, 1fr) minmax(0, 1.2fr);
  gap: 12px; align-items: center; padding: 10px 14px;
  border-top: 1px solid var(--grey-100);
}
.lib-bulk-row:first-child { border-top: 0; }
.lib-bulk-row.lib-bulk-close { background: var(--risk-limited-bg); }
.lib-bulk-name { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.lib-bulk-typed { font-size: 0.9rem; font-weight: 600; color: var(--grey-900); overflow-wrap: anywhere; }
.lib-bulk-status { font-size: 0.75rem; color: var(--grey-600); }
.lib-bulk-select { width: 100%; max-width: 100%; }
.lib-bulk-leave { font-size: 0.8rem; color: var(--grey-600); }
.lib-bulk-note { font-size: 0.8rem; color: var(--grey-700); margin: 12px 2px 0; line-height: 1.5; }
.lib-bulk-done {
  margin: 14px 0 0; padding: 10px 14px; border-radius: 10px; font-size: 0.85rem;
  background: var(--risk-minimal-bg); color: var(--grey-800);
}
.lib-bulk-done.lib-bulk-done-warn { background: var(--risk-limited-bg); }

/* On a phone the choice drops under the name. */
@media (max-width: 600px) {
  .lib-bulk-row { grid-template-columns: auto minmax(0, 1fr); }
  .lib-bulk-to { grid-column: 2; }
}

.dash-add-input-wrap .suggestions {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  z-index: 30;
  /* A floating panel under the rounded field, not a box glued to its bottom edge. */
  border: 1px solid var(--grey-200);
  border-radius: 12px;
  box-shadow: var(--shadow-md);
  padding: 4px;
}
.dash-add-input-wrap .suggestion-item { border-radius: 8px; }


/* ⭐ REDESIGN Step 3, shared building blocks (2026-09-16): the landing page's look — pill buttons, rounder cards, softer shadows, thin borders, mono tags. */


.dash-empty {
  margin-top: 28px;
  padding: 40px 20px;
  text-align: center;
  color: var(--grey-600);
  font-size: 0.95rem;
  border: 1.5px dashed var(--grey-300);
  border-radius: 16px;
  background: var(--white);
}

/* Creating a record is the paid action; the padlock sits on the button that
   does it. Deliberately still clickable — it explains itself and offers the
   upgrade, and a disabled button would show no tooltip. */
.btn-locked {
  background: var(--grey-200);
  border-color: var(--grey-200);
  color: var(--grey-600);
  cursor: not-allowed;
}
.btn-locked:hover { background: var(--grey-200); border-color: var(--grey-200); }
.btn-lock { margin-right: 2px; font-size: 0.85em; }

/* Inventory list — plain rows, no assessment UI */
.lib-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.lib-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 16px;
  background: var(--white);
  border: 1px solid var(--grey-200);
  border-radius: 14px;
  box-shadow: 0 1px 2px rgba(11, 27, 63, 0.04);
  transition: border-color 0.15s, box-shadow 0.15s, transform 0.15s;
}

.lib-item-main {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
}

.lib-item-name {
  font-family: var(--display);
  font-weight: 600;
  color: var(--grey-900);
  font-size: 1rem;
  /* fixed min-width so the tags line up in a column across rows,
     regardless of how long each software name is */
  flex: 0 0 auto;
  min-width: 240px;
}

.lib-tag {
  display: inline-block;
  padding: 3px 9px;
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
  font-family: var(--mono);
}
.lib-tag-catalog { background: var(--eu-blue-light); color: var(--eu-blue); }
/* Same blue as "In catalogue" (user, 2026-09-03). The grey read as a lesser state — a
   tool you added yourself is not a second-class entry, it is just one the catalogue does
   not know yet, and the whole point of the library is that both kinds count the same. */
.lib-tag-manual  { background: var(--eu-blue-light); color: var(--eu-blue); }

/* how far through the library you are — a bar, above the list.
   Sat on the white page it still read as furniture (user, 2026-08-24), so it gets
   its own panel, the same shape as the instructions strip above it but GREEN, so
   the two blocks are told apart at a glance. Green is already this page's word for
   done — the row chips use exactly these two colours — so it is the page's own
   language, not a risk tier leaking in. */
.lib-count-bar {
  display: flex;
  align-items: center;
  gap: 14px;
  margin: 0 0 16px;
}
/* The panel belongs to the LIBRARY LIST, where the bar stands alone at the top of a
   page and needed something to sit in. Everywhere else it sits inside a card that
   already has a frame of its own. */
.lib-list-title { font-family: var(--display); font-size: 1.05rem; font-weight: 700; color: var(--grey-900); margin: 0 2px 10px; }
.lib-list-count { font-weight: 500; color: var(--grey-600); }
#libListSection .lib-count-bar {
  padding: 12px 16px;
  background: var(--risk-minimal-bg);
  border: 1px solid #A9DFBF;
  border-left: 4px solid var(--risk-minimal);
  border-radius: var(--radius);
}
/* A risk assessment's 7px hairline reads as a rule between two things when it
   stands alone at the top of a page (user, 2026-08-24: "looks like a line separating
   thing"). This one is a TROUGH you can see when it is empty: taller, an outlined
   well with an inset shadow, and a fill that sits inside it. */
.lib-prog {
  flex: 0 1 360px;
  height: 16px;
  /* WHITE, not grey: the empty part of the bar has to stay visible against the
     green panel, or a bar at 20% looks like a bar at 100%. */
  background: var(--white);
  border: 1px solid #A9DFBF;
  border-radius: 20px;
  overflow: hidden;
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.07);
}
.lib-prog-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--risk-minimal-border), var(--risk-minimal));
  border-radius: 20px;
  transition: width 0.3s ease;
}
/* One tool out of sixty is 2% — a sliver too thin to see is worse than no bar,
   so any real progress shows as at least a visible cap. Applied only when there
   IS progress, or an empty bar would show a false first step. */
.lib-prog-fill.on { min-width: 12px; }
.lib-prog-count {
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--grey-800);
  white-space: nowrap;
}
.lib-prog-count strong { color: var(--risk-minimal); }

/* right-hand group: note sits just left of the Remove button */
.lib-item-right {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
}

/* The two-paragraph .lib-legend that explained "In catalogue" vs "Manual
   assessment" was removed with the page rewrite (2026-08-23): read once, never
   again, and the biggest block of text on the page. The tag on the row and the
   tool's own screen say it where it changes what you do. */

/* .sw-remove-btn is styled for dark panel headers (light text); on the
   white inventory rows it needs a visible dark-on-light treatment. */
.lib-item .sw-remove-btn {
  flex-shrink: 0;
  border-radius: 999px;
  border: 1px solid var(--grey-200);
  color: var(--grey-600);
  background: var(--white);
}
.lib-item .sw-remove-btn:hover {
  background: var(--risk-high-bg);
  border-color: var(--risk-high-border);
  color: var(--risk-high);
}

/* ── What this page asks of you, in three steps ──────────────────────────────
   A paragraph named the page but left a new customer with no idea what was being
   asked. The numbered steps say all of it and still read as one glance — and
   the info mark at the front is there to catch the eye of somebody who would
   otherwise scroll straight past the instructions. */
.lib-steps-wrap {
  display: flex; align-items: flex-start; gap: 12px;
  margin: 0 0 18px; padding: 14px 18px;
  background: var(--eu-blue-pale);
  border: 1px solid var(--eu-blue-light);
  border-radius: 14px;
}
.lib-steps-ico {
  flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; margin-top: 1px; border-radius: 50%;
  background: var(--eu-blue); color: #fff;
  font-size: 0.85rem; font-weight: 700; font-style: italic;
}
.lib-steps {
  list-style: none; margin: 0; padding: 0; min-width: 0;
  display: flex; flex-direction: column; gap: 7px;
}
.lib-steps li { display: flex; align-items: flex-start; gap: 9px; }
/* The step that hands off to the assessment carries the link itself — the sidebar item
   is two feet away, but a sentence naming the next thing to do should BE the way there. */
.lib-step-link {
  color: var(--eu-blue);
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.lib-step-link:hover { color: var(--eu-blue-dark); }

.lib-step-n {
  flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  width: 19px; height: 19px; margin-top: 1px; border-radius: 50%;
  background: var(--white); border: 1px solid var(--eu-blue-light);
  color: var(--eu-blue-dark); font-size: 0.72rem; font-weight: 500; font-family: var(--mono);
}
.lib-step-t { font-size: 0.85rem; line-height: 1.5; color: var(--grey-800); min-width: 0; }
.lib-step-t strong { color: var(--eu-blue-dark); font-weight: 700; }
/* A link in a step has to be told apart from the bolded terms beside it, which
   are already blue. The underline is what does that — colour alone does not. */
.lib-step-t a { color: var(--eu-blue); text-decoration: underline; text-underline-offset: 2px; }
/* Underlined emphasis inside a step. The default underline sits on the text;
   dropping it clear keeps the descenders readable at this size. */
.lib-step-t u { text-decoration-thickness: 1px; text-underline-offset: 3px; }

/* ── Round ticks, in a row ───────────────────────────────────────────────────
   Three full-width buttons with the chosen one filled solid blue read as a
   heading rather than a choice. Only the TICK fills now. Scoped to
   .ai-status-radio: Step 2 has its own copy of this control and is untouched. */
.ai-status-radio {
  padding: 16px 18px; border-radius: 14px;
  background: var(--eu-blue-pale); border: 1px solid var(--eu-blue-light);
}
/* The question is the only thing being asked on this screen for an uncatalogued
   tool, so it carries the weight of a heading rather than a caption. */
.ai-status-radio .ai-status-q {
  font-family: var(--display); font-size: 1.05rem; font-weight: 700; color: var(--eu-blue-dark); margin-bottom: 12px;
}
.ai-status-radio .ai-status-btns { flex-direction: row; flex-wrap: wrap; gap: 10px; }
.ais-opt {
  display: inline-flex; align-items: center; gap: 9px;
  font: inherit; font-size: 0.85rem; color: var(--grey-800); cursor: pointer;
  padding: 8px 15px 8px 12px; border-radius: 999px;
  border: 1px solid var(--grey-300); background: var(--white);
  transition: border-color .12s, background .12s;
}
.ais-opt:hover { border-color: var(--eu-blue); }
.ais-opt:focus-visible { outline: 2px solid var(--eu-blue); outline-offset: 2px; }
.ais-opt.selected {
  border-color: var(--eu-blue); background: var(--eu-blue-pale);
  color: var(--eu-blue-dark); font-weight: 600;
}
.ais-dot {
  position: relative; flex: 0 0 auto; width: 15px; height: 15px;
  border-radius: 50%; border: 2px solid var(--grey-400); background: var(--white);
}
.ais-opt.selected .ais-dot { border-color: var(--eu-blue); }
.ais-opt.selected .ais-dot::after {
  content: ""; position: absolute; inset: 2px; border-radius: 50%; background: var(--eu-blue);
}

/* ── A labelled field ────────────────────────────────────────────────────────
   Only on the features the customer named. Their own two lines arrive as bare
   text with nothing to say which is the name and which is the description. A
   CATALOGUE row already carries a vendor source line, and six of them in a column
   would print "AI FEATURE" six times — noise of its own. */
.lp-field { display: flex; gap: 10px; align-items: baseline; margin-top: 5px; }
.lp-field:first-child { margin-top: 0; }
/* Wide enough for the longest label, and it may NEVER wrap: "THIS FEATURE ADDED
   BY" was breaking after "ADDED", which knocked its value out of line with the
   three above it. A fixed column is what puts every value on the same left edge. */
.lp-field-label {
  flex: 0 0 176px; white-space: nowrap;
  font-family: var(--mono); font-size: 0.72rem; font-weight: 500; letter-spacing: 0.02em;
  text-transform: uppercase; color: var(--grey-500); line-height: 1.65;
}
/* The feature name is what a reader scans the card for, and with the switch gone from
   this screen there is nothing else on the row competing for the eye. An underline that
   sits clear of the descenders, rather than a heavier weight — the label above it is
   already bold, and two bold things next to each other cancel out.
   THIN AND UNBROKEN (user, 2026-09-04). At 2px the rule read as heavy, and the browser
   cuts a gap in it wherever a letter hangs through, so a name with a g, y or p came out
   as a dashed line. skip-ink: none draws it straight through, and 1px at a 4px offset
   keeps it clear of the descenders it now crosses under. */
.lp-featname {
  font-weight: 600;
  color: var(--eu-blue-dark);
  text-decoration: underline;
  text-decoration-color: var(--eu-blue-mid);
  text-decoration-thickness: 1px;
  text-decoration-skip-ink: none;
  text-underline-offset: 4px;
}
/* The mark on a conditional feature is a mark, not part of the name, and an underline
   running under a glyph set at 1.35em is the other place the line looked broken. An
   atomic inline box is not decorated by its ancestor, which is what takes it out. */
.lp-featname .caveat-mark { display: inline-block; text-decoration: none; }

.lp-field-val { min-width: 0; flex: 1 1 auto; }
/* ONE font and ONE colour for every value (user, 2026-08-23). The name came from
   .feature-name and the description from .feature-desc, so two labelled lines
   sitting under each other were different sizes and different greys for no reason
   a reader could work out. */
.lp-field-val,
.lp-field-val .feature-name,
.lp-field-val .feature-desc {
  margin: 0; font-size: 0.85rem; font-weight: 500; line-height: 1.5; color: var(--grey-800);
}
.lp-field-val .uf-nonote { font-style: italic; color: var(--grey-600); }

/* THE LEVEL FIELD (2026-08-24). The badge and the link that explains it, on one
   line, in the same labelled column as everything else that describes the feature.
   The link used to sit at the bottom of the OTHER column, where the user read it
   as unrelated to the badge. */
.lp-level { display: inline-flex; align-items: center; gap: 10px; flex-wrap: wrap; }
/* The disclosure is a link beside a badge here, not a block of its own. */
.lp-level .why-toggle { margin: 0; }
/* What comes back if it is switched on. Small and quiet: the badge carries the
   state, this only has to be there when somebody looks for it. */

.lp-offnote {
  display: block;
  margin-top: 3px;
  font-size: 0.8rem;
  color: var(--grey-600);
}
/* A "Others while switched off" badge is a sentence, not a word, so it must be
   allowed to wrap — .risk-pill is nowrap for the short names. */
.lp-field-val .risk-pill.inactive { white-space: normal; }

/* Edit and Remove, as a matched pair of icons on the RIGHT. Two word-buttons under
   a column of labelled fields read as more content; identical round icons, pushed
   right, read as controls for the row. Same size, same border, same weight — only
   the hover colour differs, because one of them deletes something. */
.lp-actions { display: flex; gap: 6px; justify-content: flex-end; margin-top: 4px; }
/* COLOURED, not grey (user, 2026-08-23: "make them stand out a bit as its all
   grey"). Everything else in this column is grey or white, so grey icons vanished.
   Tinted from the start rather than only on hover — a control nobody can see is
   not a control. Blue for edit, red for remove: one of them deletes something. */
.lp-ico-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; padding: 0; border-radius: 50%; cursor: pointer;
  font: inherit; font-size: 0.9rem; line-height: 1;
  border: 1.5px solid; transition: color .12s, background .12s, border-color .12s;
}
.lp-ico-edit { border-color: rgba(0,51,153,0.35); color: var(--eu-blue); background: var(--eu-blue-pale); }
.lp-ico-edit:hover { border-color: var(--eu-blue); background: var(--eu-blue); color: #fff; }
.lp-ico-remove { border-color: rgba(220,38,38,0.35); color: #dc2626; background: var(--risk-high-bg); }
.lp-ico-remove:hover { border-color: #dc2626; background: #dc2626; color: #fff; }
.lp-ico-btn:focus-visible { outline: 2px solid var(--eu-blue); outline-offset: 2px; }

/* ⛔ .fm-edit IS GONE (user, 2026-09-10) with the ✎ Edit button it styled. */
.fm-label-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }

/* The library's own fields, in the library's order, so the dialog shows what the
   tool card shows rather than a run-on line that was less than either. */
.fm-field { display: flex; gap: 8px; align-items: baseline; margin-top: 3px; }
.fm-field-label {
  flex: 0 0 94px; font-family: var(--mono); font-size: 0.72rem; font-weight: 500; letter-spacing: 0.02em;
  text-transform: uppercase; color: var(--grey-500); line-height: 1.65; white-space: nowrap;
}
.fm-field-val { min-width: 0; }
.fm-nonote { font-style: italic; color: var(--grey-600); }

/* The recorded switch, STATED not offered — it is set against the software, once,
   with a date and a history behind it. Given a strip of its own rather than a line
   in the field list: it is the one thing on the row that a reader is checking, and
   both the customer and an auditor should find it without hunting. Colour separates
   the four states at a glance; the words still carry the meaning, so the colour is
   never the only thing saying which one it is. */
.fm-switch {
  display: flex; align-items: baseline; gap: 10px;
  margin: 7px 0; padding: 6px 12px; border-radius: 0 8px 8px 0;
  border-left: 3px solid var(--grey-400); background: var(--grey-100);
}
.fm-switch-label {
  flex: 0 0 auto; font-family: var(--mono); font-size: 0.72rem; font-weight: 500; letter-spacing: 0.02em;
  text-transform: uppercase; color: var(--grey-600);
}
.fm-switch-val { font-size: 0.9rem; font-weight: 700; letter-spacing: 0.02em; }

/* ON is the state that means AI is running, so it is the loudest. */
.fm-switch-on { border-left-color: var(--eu-blue); background: var(--eu-blue-light); }
.fm-switch-on .fm-switch-val { color: var(--eu-blue-dark); }
.fm-switch-on .fm-switch-label { color: var(--eu-blue); }

/* ⛔ OFF IS NOT GREEN (user, 2026-09-10: "make off darker grey"). Green is the app's
   "done / lowest risk" colour, and the Step 1 buttons are neutral on purpose — green
   for off would say switching it off is the "right" answer. Off is a plain fact, so
   it wears a darker grey than the default strip: settled, not celebrated. */
.fm-switch-off { border-left-color: var(--grey-700); background: var(--grey-200); }
.fm-switch-off .fm-switch-val { color: var(--grey-800); }
.fm-switch-off .fm-switch-label { color: var(--grey-700); }

/* The two that leave something open. */
.fm-switch-notsure,
.fm-switch-none {
  border-left-color: var(--risk-limited); background: var(--risk-limited-bg);
}
.fm-switch-notsure .fm-switch-val,
.fm-switch-none .fm-switch-val { color: var(--risk-limited); }
/* ⛔ .fm-empty IS GONE (user, 2026-09-10) — the picker shows no "no features yet" message. */


/* What is still needed after "has AI, we don't use it" (2026-08-24). Appears only
   in the one state that reads as finished but is not. */
.ais-followup {
  margin: 0 0 12px;
  padding: 9px 12px;
  border-left: 3px solid var(--eu-blue);
  border-radius: var(--radius-sm);
  background: var(--eu-blue-pale);
  font-size: 0.8rem;
  line-height: 1.5;
  color: var(--grey-800);
}

/* The ⚠ rule, on the row it applies to (2026-08-24). It used to be one legend above
   the whole list, where "only counts if you actually do this" had nothing to point
   at. Amber like the mark itself, and tight under the condition it refers to. */
.tc-caveat-row {
  margin: 5px 0 2px;
  padding: 7px 10px;
  border-left: 3px solid var(--risk-limited);
  border-radius: var(--radius-sm);
  background: var(--risk-limited-bg);
  font-size: 0.8rem;
  line-height: 1.5;
  color: var(--grey-800);
}
.tc-caveat-row .caveat-mark { margin-right: 4px; }
.fm-opt-note .tc-caveat-row { margin: 6px 0; }

/* A feature the vendor has dropped (phase47). It is only on screen at all because
   THIS customer answered it, so it is marked rather than removed — grey, because it
   is a fact about the catalogue, not a risk finding. */
.lp-retired {
  display: inline-block; margin-left: 8px; padding: 1px 8px; border-radius: 999px;
  background: var(--grey-100); color: var(--grey-600);
  font-family: var(--mono); font-size: 0.72rem; font-weight: 500; text-transform: uppercase; letter-spacing: 0.02em;
  white-space: nowrap; vertical-align: middle;
}
.lp-retired-note {
  margin-top: 5px; padding: 7px 10px; border-radius: var(--radius-sm);
  border-left: 3px solid var(--grey-400); background: var(--grey-50);
  font-size: 0.8rem; line-height: 1.5; color: var(--grey-700);
}

/* ── The tool's own note (phase46) ───────────────────────────────────────────
   The business's words about the tool, between the features and the history: not
   the work above it, not the record below it. One box per tool. */
.lp-notes { margin-top: 14px; }
.lp-notes-label {
  display: block; margin-bottom: 7px;
  font-family: var(--mono); font-size: 0.72rem; font-weight: 500; text-transform: uppercase; letter-spacing: 0.02em;
  color: var(--eu-blue);
}
.lp-notes-opt { font-family: var(--font); font-weight: 600; text-transform: none; letter-spacing: 0; color: var(--grey-600); }
.lp-notes-box {
  display: block; width: 100%; box-sizing: border-box;
  padding: 10px 12px; border: 1px solid var(--grey-300); border-radius: 12px;
  font: inherit; font-size: 0.85rem; line-height: 1.5; color: var(--grey-800);
  background: var(--white); resize: vertical;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.lp-notes-box:focus { outline: none; border-color: var(--eu-blue); box-shadow: 0 0 0 3px rgba(0, 51, 153, 0.12); }
.lp-notes-box::placeholder { color: var(--grey-500); }

/* The same note in the report — read, not written, so it is a quoted block. */
.rpt-tool-note {
  margin-top: 10px; padding: 9px 12px;
  border-left: 3px solid var(--eu-blue); border-radius: 0 8px 8px 0;
  background: var(--eu-blue-pale);
}
.rpt-tool-note-label {
  display: block; margin-bottom: 3px;
  font-size: 0.66rem; font-weight: 500; text-transform: uppercase; letter-spacing: 0.02em;
  color: var(--eu-blue);
  font-family: var(--mono);
}
.rpt-tool-note-text { font-size: 0.8rem; line-height: 1.5; color: var(--grey-800); white-space: pre-wrap; }

/* ── The history of one tool ─────────────────────────────────────────────────
   Below the features, in a card of its own: a record to consult, not part of the
   work somebody came here to do. Quiet by design — dates in a fixed column so the
   eye runs down them, and the sentence beside each one. */
.lp-log {
  margin-top: 16px; padding: 16px 18px;
  background: var(--white); border: 1px solid var(--grey-200);
  border-radius: 16px; box-shadow: 0 1px 2px rgba(11, 27, 63, 0.04);
}
.lp-log-head {
  font-family: var(--mono); font-size: 0.72rem; font-weight: 500; letter-spacing: 0.02em;
  text-transform: uppercase; color: var(--grey-500); margin-bottom: 10px;
}
.lp-log-list { list-style: none; margin: 0; padding: 0; }
.lp-log-row {
  display: flex; gap: 14px; align-items: baseline;
  padding: 7px 0; border-top: 1px solid var(--grey-100);
}
.lp-log-row:first-child { border-top: none; }
/* Fixed width so the dates line up as a column rather than a ragged edge. */
.lp-log-date {
  flex: 0 0 108px; white-space: nowrap;
  font-family: var(--mono); font-size: 0.75rem; font-weight: 500; color: var(--grey-600);
}
.lp-log-what { min-width: 0; font-size: 0.8rem; line-height: 1.5; color: var(--grey-800); }
.lp-log-what strong { color: var(--eu-blue-dark); font-weight: 700; }
.lp-log-empty { font-size: 0.8rem; line-height: 1.5; color: var(--grey-600); }
.lp-log-more {
  margin-top: 10px; padding: 0; border: none; background: none; cursor: pointer;
  font: inherit; font-size: 0.8rem; font-weight: 700; color: var(--eu-blue);
}
.lp-log-more:hover { text-decoration: underline; }

@media (max-width: 620px) {
  .lp-log-row { flex-direction: column; gap: 2px; }
  .lp-log-date { flex: 0 0 auto; }
}

/* ── A library row is a link to that tool's own screen ───────────────────────
   The card used to open inside the list, and the list then stopped being a list.
   The row is back to one line — name, tag, state, Remove — and everything about
   the tool's AI features lives on its own screen, which re-uses Step 2's feature
   rows, switches and pills: the same question, so it must not look like a second,
   different one. */
.lib-item-link { cursor: pointer; }
.lib-item-link:hover { border-color: var(--eu-blue); background: var(--white); box-shadow: 0 12px 28px -16px rgba(11, 27, 63, 0.35); transform: translateY(-1px); }
.lib-item-link:focus-visible { outline: 2px solid var(--eu-blue); outline-offset: 2px; }
.lib-item-go { color: var(--grey-400); font-size: 1.1rem; line-height: 1; }
.lib-item-link:hover .lib-item-go { color: var(--eu-blue); }

/* WORDS, not a fraction. "0 of 7 checked" counted features — our unit, not the
   customer's. Nobody thinks "I have 7 features in Figma"; they think "have I
   looked at Figma yet". */
.lp-chip {
  font-size: 0.8rem; font-weight: 700; white-space: nowrap;
  padding: 2px 10px; border-radius: 20px;
  background: var(--grey-100); color: var(--grey-600);
}
.lp-chip-todo { background: var(--risk-limited-bg); color: var(--risk-limited); }
.lp-chip-part { background: var(--risk-limited-bg); color: var(--risk-limited); }
.lp-chip-done { background: var(--risk-minimal-bg); color: var(--risk-minimal); }

/* ── One tool's screen ──────────────────────────────────────────────────────── */
.lp-head { margin: 4px 0 16px; }
.lp-head-top { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.lp-head-name { margin: 0; font-family: var(--display); font-size: 1.5rem; font-weight: 700; letter-spacing: -0.015em; color: var(--grey-900); }
/* Everything that used to crowd the list row — when it was added, how many
   features are documented, when the catalogue last looked — one grey line here. */
/* Under the tool's name, over a list the reader would otherwise take as complete.
   A button, because it DOES something — it opens the Add form at the foot of the card
   and scrolls to it — but it reads as the question it is asking. */
.lp-head-add {
  display: block; margin: 6px 0 0; padding: 0;
  font: inherit; font-size: 0.8rem; text-align: left;
  color: var(--grey-800); background: none; border: 0; cursor: pointer;
}
.lp-head-add-do {
  color: var(--eu-blue); font-weight: 600;
  text-decoration: underline; text-underline-offset: 2px;
}
.lp-head-add:hover .lp-head-add-do { color: var(--eu-blue-dark); }
.lp-head-add:focus-visible { outline: 2px solid var(--eu-blue); outline-offset: 3px; }

.lp-head-meta { margin-top: 6px; font-size: 0.8rem; color: var(--grey-600); }

/* A thin blue line just inside the card edge — a frame within the frame. Drawn on
   a pseudo-element so it costs no layout: the card gains a little padding, the
   line sits in it, and nothing inside has to know it is there. Quiet on purpose
   (the brand blue at a third strength): the page already spends real blue on the
   risk pills and the instructions panel, and a strong line here would compete
   with both. pointer-events:none so it can never swallow a click. */
.lp-card { position: relative; padding: 9px; overflow: hidden; }
.lp-card::before {
  content: ""; position: absolute; inset: 4px; pointer-events: none;
  border: 1px solid rgba(0, 51, 153, 0.32);
  border-radius: 12px;   /* the card's 16px less the 4px inset, so the two curves run parallel */
  z-index: 1;
}
/* Everything inside sits clear of the line rather than crossing it. */
.lp-card > .tc-nothing,
.lp-card > .ai-status,
.lp-card > .uf-add { margin: 10px; }
.lp-card > /* When this tool’s features were last read off the vendor’s site. Once, above the
   list — it used to be a sentence on every row saying the same thing. */
.sw-panel-checked {
  font-size: 0.8rem;
  color: var(--grey-600);
  margin-bottom: 8px;
}

/* .sw-panel-intro was the other half of this selector; removed 2026-09-12 with the class. */
.lp-card > .sw-panel-missing:first-child { border-radius: calc(var(--radius) - 6px) calc(var(--radius) - 6px) 0 0; }
.lp-card > .feature-row:last-of-type { border-bottom: none; }

/* One small grey line for a feature the customer named: who oversees it
   (Article 26(2) wants a name against the thing) and when they added it. It was
   three separate lines, each at full weight. */

/* The date sits with the ANSWER, under the buttons — it is a fact about the
   answer, not about the feature. */

@media (max-width: 760px) {
  /* A 152px label column leaves nothing for the value on a phone, so the label
     goes above it instead of squeezing it into a ribbon. */
  .lp-field { flex-direction: column; gap: 1px; }
  .lp-field-label { flex: 0 0 auto; }
  .lib-item { flex-wrap: wrap; }
  .lib-item-name { min-width: 0; }
}


/* ── Risk Assessments ── */
.ra-list-actions { margin-bottom: 16px; }

.btn-sm { height: 32px; padding: 0 12px; font-size: 0.8rem; }

.ra-list { display: flex; flex-direction: column; gap: 10px; }

.ra-card {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 18px;
  background: var(--white);
  border: 1px solid var(--grey-200);
  border-radius: 14px;
  box-shadow: 0 1px 2px rgba(11, 27, 63, 0.04);
  transition: border-color 0.15s, box-shadow 0.15s;
}
.ra-card-main { flex: 1; min-width: 0; cursor: pointer; }
.ra-card-top { display: flex; align-items: center; gap: 10px; }
.ra-card-num { font-weight: 700; color: var(--grey-900); font-size: 1rem; font-family: var(--display); }
.ra-card-meta { font-size: 0.8rem; color: var(--grey-600); margin: 4px 0 8px; }
/* The shared progress bar carries a bottom margin for the library page, where it
   stands alone above a list. Inside a record card it is the last thing in the card,
   so the card's own padding is the space below it — otherwise the card ends with
   30px of nothing. Applies to both lists, which is the point: an assessment card
   and a tracker card are the same shape (2026-08-25). */
.ra-card-main .lib-count-bar:last-child { margin-bottom: 0; }
.ra-status {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-family: var(--mono);
}
.ra-status.draft  { background: var(--grey-100); color: var(--grey-600); }
.ra-status.locked { background: var(--risk-minimal-bg); color: var(--risk-minimal); }
/* Locked but the Article 25 statement was never confirmed — no tracker. */
.ra-status.unconfirmed { background: var(--risk-limited-bg); color: var(--risk-limited); }

/* Transparency duty the provider owes: shown, attributed, not tickable. */
.rpt-done.provider { color: var(--grey-600); font-style: italic; }


.ra-back-btn { margin-bottom: 14px; }

.ra-meta-card { padding: 20px 24px; }
.ra-meta-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.ra-meta-num { font-family: var(--display); font-size: 1.4rem; font-weight: 700; letter-spacing: -0.015em; color: var(--grey-900); }
.ra-meta-sub { font-size: 0.8rem; color: var(--grey-600); margin-top: 3px; }
.ra-meta-inputs {
  display: flex;
  flex-wrap: wrap;
  gap: 14px 18px;
  align-items: flex-end;
  background: var(--eu-blue-pale);
  border: 1px solid var(--eu-blue-light);
  border-radius: 14px;
  padding: 14px 16px;
}
.ra-meta-field { display: flex; flex-direction: column; gap: 4px; }
.ra-meta-label { font-family: var(--mono); font-size: 0.72rem; font-weight: 500; text-transform: uppercase; letter-spacing: 0.02em; color: var(--eu-blue-dark); }
.ra-meta-input { height: 40px; min-width: 220px; border: 1px solid var(--eu-blue); background: var(--white); }
.ra-meta-input:focus { border-color: var(--eu-blue-dark); }
.ra-meta-inputs .ra-meta-sub { flex-basis: 100%; margin-top: 0; }
.ra-meta-progress { display: flex; align-items: center; gap: 12px; margin-top: 14px; }
/* The shared bar carries its own bottom margin for the library page, where it stands
   alone above a list. Here it sits in a row beside the catalogue/manual count, so the
   row does the spacing (2026-08-25 — the header was made to match the list card). */
.ra-meta-progress .lib-count-bar { flex: 1; margin: 0; }

.ra-locked-notice {
  margin-top: 14px;
  padding: 10px 14px;
  background: var(--risk-minimal-bg);
  border: 1px solid var(--risk-minimal-border);
  border-radius: 12px;
  color: var(--risk-minimal);
  font-size: 0.85rem;
}

.ra-builder-actions {
  margin-top: 20px;
  display: flex;
  gap: 10px;
  justify-content: flex-end;
}

/* RA never shows the software remove button (membership mirrors the library) */
#raToolsList .sw-remove-btn { display: none; }

/* locked assessment is read-only — both steps. Without this a locked record
   could be re-answered, and a locked record is the whole point. */
.ra-readonly #raUsesList,
.ra-readonly #raToolsList { pointer-events: none; opacity: 0.9; }
/* …but a locked assessment opens collapsed, so the controls that reveal its
   content must stay clickable. Without this the record is unreadable.
   Only the reveal controls — NOT ✕ Remove, which must stay dead. */
.ra-readonly .sw-collapse-btn,
.ra-readonly .why-toggle,
.ra-readonly .use-act { pointer-events: auto; }
.ra-readonly .sw-remove-btn { pointer-events: none; opacity: 0.35; }

/* ── The demo company ──────────────────────────────────────────
   A worked example, not the reader's work. It is view-only in the same way a
   locked assessment is: everything reads, nothing takes an edit. The tracker
   needs its own rule because it has no locked state of its own — a real tracker
   is meant to be ticked. */
.at-readonly .at-card { pointer-events: none; opacity: 0.9; }
/* …except the controls that reveal content, or the example cannot be read. */
.at-readonly .at-ob-info { pointer-events: auto; }
.at-readonly textarea,
.at-readonly input { pointer-events: none; }
/* The card in the list. Distinct enough to read as an example at a glance,
   quiet enough not to compete with the customer's own records. */
.ra-card-demo { border-style: dashed; cursor: pointer; }
.ra-card-demo:hover { border-color: var(--eu-blue); }
.ra-status.demo {
  background: var(--eu-blue);
  color: #fff;
}

/* ── Article 25 attestation, required before locking ───────────── */
.ra-attest {
  margin-top: 22px;
  padding: 16px 18px;
  background: var(--risk-high-bg);
  border: 1px solid var(--risk-high-border);
  border-radius: 16px;
}
.ra-attest-head { display: flex; align-items: center; gap: 10px; }
.ra-attest-icon { font-size: 1.2rem; }
.ra-attest-title {
  margin: 0;
  font-family: var(--display);
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--risk-high);
}
.ra-attest-body {
  margin: 10px 0 8px;
  font-size: 0.85rem;
  color: var(--grey-700);
  line-height: 1.65;
}
.ra-attest-list {
  margin: 0 0 12px;
  padding-left: 20px;
  font-size: 0.85rem;
  color: var(--grey-700);
  line-height: 1.65;
}
.ra-attest-list li { margin-bottom: 4px; }
.ra-attest-check {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--grey-800);
  line-height: 1.5;
  cursor: pointer;
}
.ra-attest-check input { margin-top: 2px; width: 17px; height: 17px; flex-shrink: 0; cursor: pointer; }
.ra-attest-check input:disabled { cursor: default; }
.ra-attest-note {
  margin: 10px 0 0;
  font-size: 0.8rem;
  color: var(--risk-high);
  line-height: 1.5;
}
.ra-attest-done {
  margin: 10px 0 0;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--risk-minimal);
}
/* Once ticked, the box stops shouting. */
.ra-attest-confirmed {
  background: var(--risk-minimal-bg);
  border-color: var(--risk-minimal-border);
}
.ra-attest-confirmed .ra-attest-title { color: var(--risk-minimal); }
/* Locked: the tick is a permanent record, not an editable control — unless it
   was never given, in which case it stays available (it only adds a statement,
   and without it the Actions Tracker cannot be built). */
.ra-readonly .ra-attest { pointer-events: none; }
.ra-readonly .ra-attest-live { pointer-events: auto; }

/* ── Slim dashboard footer (legal links + positioning) ── */
.dash-footer {
  flex-shrink: 0;   /* stay pinned below the flex-growing content */
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 18px;
  padding: 16px 28px;
  border-top: 1px solid var(--grey-200);
  background: #fff;
  font-size: 0.8rem;
  color: var(--grey-500);
}
.dash-footer-links { display: flex; gap: 14px; flex-wrap: wrap; }
.dash-footer a { color: var(--eu-blue); text-decoration: none; }
.dash-footer a:hover { text-decoration: underline; }
.dash-footer-note { flex: 1 1 auto; min-width: 200px; }
.dash-footer-copy { margin-left: auto; white-space: nowrap; }


/* Article 25 attestation, printed as a recorded fact in the report. */
/* Full width, 18px inset under the bar — see .rpt-actions-section (2026-10-07). */
.rpt-attest-section { margin-top: 26px; padding: 0 0 8px; }
.rpt-attest-section > :not(.rpt-sec-head) { margin-left: 18px; margin-right: 18px; }
.rpt-attest-text { font-size: 0.85rem; color: var(--grey-800); line-height: 1.65; margin: 8px 0; }
/* Report §1 Scope (2026-09-21). */
.rpt-scope-k { margin: 14px 0 0; font-size: 0.72rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em; color: var(--grey-600); }
.rpt-scope-note { font-weight: 400; text-transform: none; letter-spacing: 0; }
.rpt-scope-list { margin: 6px 0 8px 18px; padding: 0; font-size: 0.85rem; color: var(--grey-800); line-height: 1.6; }
.rpt-attest-section > .rpt-scope-list { margin-left: 36px; }
.rpt-attest-meta { font-size: 0.8rem; color: var(--grey-600); line-height: 1.5; margin: 6px 0; }


/* ── Actions Taken ── */
.at-picker { padding: 16px 18px; margin-bottom: 16px; }
.at-picker-title { font-weight: 700; color: var(--eu-blue-dark); margin-bottom: 10px; font-size: 1rem; font-family: var(--display); }

/* ── "Report prepared by", above the record list ─────────────────────────────
   ⚠ THE WORD "optional" IS ON THE LABEL, not only in the hint. This box sits
   directly above the buttons that CREATE the report, so anything reading as
   required would stop somebody who has nobody to name — and nobody to name is a
   legitimate answer: the report stands on the locked assessment behind it. */
.rp-by-label {
  display: flex; align-items: baseline; gap: 8px; margin-bottom: 5px;
  font-weight: 700; color: var(--eu-blue-dark); font-size: 0.9rem;
}
.rp-by-opt {
  font-size: 0.72rem; font-weight: 500; letter-spacing: 0.02em; text-transform: uppercase;
  color: var(--grey-600); background: var(--grey-100);
  border-radius: 999px; padding: 1px 8px;
  font-family: var(--mono);
}
.rp-by-input {
  display: block; width: 100%; max-width: 420px; box-sizing: border-box;
  font: inherit; font-size: 0.9rem; padding: 8px 10px;
  border: 1px solid var(--grey-300); border-radius: 10px; background: var(--white);
  transition: border-color 0.15s, box-shadow 0.15s;
}
.rp-by-input:focus { outline: none; border-color: var(--eu-blue); box-shadow: 0 0 0 3px rgba(0, 51, 153, 0.12); }
.rp-by-hint {
  margin: 6px 0 16px; max-width: 560px;
  font-size: 0.8rem; line-height: 1.5; color: var(--grey-600);
}
.at-picker-item {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 10px 12px;
  margin-bottom: 6px;
  background: var(--grey-50);
  border: 1px solid var(--grey-200);
  border-radius: 12px;
  cursor: pointer;
  text-align: left;
}
.at-picker-item:hover { border-color: var(--eu-blue); background: var(--eu-blue-light); }
.at-picker-num { font-weight: 700; color: var(--eu-blue-dark); font-family: var(--display); }
.at-picker-date { font-size: 0.8rem; color: var(--grey-600); }

/* ⛔ THE .at-literacy* CARD RULES ARE GONE (2026-09-14). The green AI-literacy card
   was rebuilt out of an ordinary obligation row (.at-lit-note, further down) and no
   .js or .html has written any .at-literacy class since. test-at-layout.js asserted
   two of these rules existed; those checks went with them. */

/* ── Row notes: HOW this feature's duties are addressed ───────────
   A tick says a duty is met; the note says how. One per row, collapsed until
   asked for — the grid is the overview and must stay scannable. */
/* Labelled, not a bare glyph. The first version was a 40%-opacity 🗒 tucked beside
   the software name — invisible in a grid of tick boxes, and on Windows that
   codepoint renders as a faint monochrome outline. Nobody hunts for a control
   they cannot see. ✎ (U+270E) is the same mark the sidebar already uses, so it
   is known to render here. */
/* A written note is a fact about the record — it reads as filled, not an invitation. */
.at-note-input {
  width: 100%; box-sizing: border-box; resize: vertical;
  font: inherit; font-size: 0.85rem; line-height: 1.5;
  padding: 8px 10px;
  border: 1px solid var(--grey-300); border-radius: 10px;
  background: #fff; color: var(--grey-800);
  transition: border-color 0.15s, box-shadow 0.15s;
}
.at-note-input:focus { outline: none; border-color: var(--eu-blue); box-shadow: 0 0 0 3px rgba(0, 51, 153, 0.12); }
.at-note-state { min-height: 14px; margin-top: 3px; font-size: 0.72rem; color: var(--grey-600); }
.at-note-state-err { color: var(--risk-high); font-weight: 700; }

/* ── Actions Tracker: one CARD per software → AI feature ─────────────────────
   Replaced a matrix (features down the side, one column per obligation) that
   needed a sideways scrollbar, a nested up-down scrollbar in a height-capped
   box, and two pinned columns so you could tell which row you were on. Three of
   its six columns repeated the same value for every duty of a feature.
   The card says the tool and the feature ONCE, in a heading with room for a
   long name; the duties list underneath in three columns that always fit. */
/* The tier is already named by the selected tab, so the card takes its accent
   from the tab rather than repeating the word. */
.at-tier-Limited      .at-card { border-left-color: var(--risk-limited); }
.at-tier-Minimal      .at-card { border-left-color: var(--risk-minimal); }
.at-tier-Unacceptable .at-card { border-left-color: var(--risk-unacceptable); }
/* Every duty on this feature is ticked. Same green as the literacy card, so
   "finished" reads the same wherever it appears. */
.at-card-head {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 12px;
  padding: 11px 14px;
  background: var(--grey-50);
  border-bottom: 1px solid var(--grey-200);
}
.at-card-names { min-width: 0; }
/* The AI FEATURE is the subject of the card — it is the thing being documented,
   and the thing that carries the duty. The software is where it lives, so it
   reads as a kicker above the name rather than the headline. */
.at-card-sw {
  font-size: 0.85rem; font-weight: 700; line-height: 1.5; color: var(--grey-900);
}
/* A feature name can be a whole declared use — up to ~170 characters. In the old
   grid that was a cell; here it has the width of the card and simply wraps.
   ⚠ min-width: 0 for the same reason as .at-feat-btn-feat in the rail: this is a
   flex item, a flex item will not shrink below its longest unbreakable word, and
   the ⓘ beside it now competes for the same line. Fixed here at the same time
   because it is one defect in two places, not two defects. */
.at-card-feat {
  min-width: 0; overflow-wrap: anywhere;
  font-size: 1rem; font-weight: 700; line-height: 1.5; color: var(--grey-900);
  font-family: var(--display);
  letter-spacing: -0.01em;
}

/* ── Tracker: show only some of the software ─────────────────────────────────
   Right-aligned above the cards, and only drawn when a tab holds more than one
   tool. A <details> rather than a scripted menu: it opens and closes on its own,
   and re-rendering the grid after every tick would otherwise shut it — the open
   state is written back so the markup can restore it. */
/* tick · duty · date · ⓘ — the two fixed ends hold their width, the label takes
   what is left, so nothing ever needs to scroll sideways. */
.at-duty-label { min-width: 0; color: var(--grey-800); line-height: 1.35; }
/* ⛔ .at-duty-date IS GONE (user, 2026-09-06). It was a bare grey word sitting in
   a column of its own — "in force since 2 Feb 2025" beside the duty, in a fourth
   grid column that printed nothing on eight rows in ten and existed only to keep
   the others in line.
   ⭐ .at-duty-tag REPLACES IT, in the same shape as the "applies to all" tag the
   literacy row already wore — the user asked for one format, and a date and a
   scope note are the same KIND of thing: a standing fact about the duty, not part
   of its name. On an obligation row it sits UNDER the name; on the literacy row it
   sits beside "applies to all", because that row's name is two words long. */
.at-duty-tag {
  display: inline-block; margin-left: 6px; padding: 1px 8px;
  border-radius: 999px; vertical-align: middle;
  font-size: 0.72rem; font-weight: 500; white-space: nowrap;
  color: var(--eu-blue-dark); background: var(--white); border: 1px solid var(--eu-blue-light);
  font-family: var(--mono);
}
/* ⚠ AMBER SURVIVES FOR A DATE THAT HAS NOT ARRIVED — the same amber as Step 1's
   "not yet" chip, so a future date reads the same wherever it appears in the app.
   It is the one case where the tag is NOT saying the same kind of thing as the
   others: everything else on a row is true now. */
.at-duty-tag.future {
  color: #8a5a00; background: #fff8e6; border-color: #f0d9a0;
}
/* ⛔ .at-ob-when WAS A LINE UNDER THE DUTY, for one afternoon (user, 2026-09-06:
   "move pills with dates next to obligations not under"). The tag rides inside
   .at-duty-label now, after the name and any external-regime badge — the same
   place and the same order the literacy row puts its two tags in. */
/* Named beside the duty, not starred against a footnote — a card has the room. */
.at-ext-badge {
  display: inline-block; margin-left: 6px; padding: 0 8px; vertical-align: middle;
  font-size: 0.72rem; font-weight: 500; letter-spacing: 0.02em; white-space: nowrap;
  color: var(--grey-600); background: var(--grey-50);
  border: 1px solid var(--grey-200); border-radius: 999px;
  font-family: var(--mono);
}

/* The org's entity type changed after this tracker was built, so its frozen
   duties may no longer match the organisation. Same amber note as .at-ext-note,
   sitting in the tracker's meta card rather than under the grid. */
.at-entity-note {
  margin-top: 8px;
  max-width: 60ch;
  font-size: 0.8rem;
  line-height: 1.5;
  color: var(--grey-700);
  background: var(--risk-limited-bg);
  border: 1px solid var(--risk-limited-border);
  border-radius: 10px;
  padding: 9px 12px;
}

/* ── Actions Taken: obligation explanation panel ── */
/* ── The tracker body: the feature panel, and a rail beside it ───────────────
   The rail answers "where am I and what else is there" — one button per AI
   feature at this risk level, each with its own progress, so moving between
   them is a click rather than a scroll. It is STICKY rather than fixed: the
   explanation panel shares the column, and a fixed panel over a sticky rail
   covered the very list it was opened from.
   300px / 28px: a wider rail and more air, because the buttons carry a risk pill as
   well as a name and a bar. (A second rule further down used to set these over the
   first rule's 272px / 20px, which did nothing — merged 2026-09-16.) */
.at-builder-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  gap: 28px;
  align-items: start;
}
#atGridWrap { min-width: 0; }
.at-rail { position: sticky; top: 84px; display: flex; flex-direction: column; gap: 14px; }
.at-ob-panel {
  max-height: calc(100vh - 120px);
  overflow-y: auto;
  background: var(--white);
  border: 1px solid var(--grey-200);
  border-radius: 16px;
  padding: 16px 18px;
  box-shadow: var(--shadow-lg);
  z-index: 30;
}
.at-ob-panel.hidden { display: none; }
.at-ob-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.at-ob-title { font-weight: 700; color: var(--grey-900); font-size: 1.05rem; line-height: 1.35; font-family: var(--display); }
.at-ob-close {
  flex: none; border: none; background: none; cursor: pointer;
  font-size: 0.95rem; color: var(--grey-500); line-height: 1; padding: 2px 4px;
}
.at-ob-close:hover { color: var(--eu-blue-dark); }
.at-ob-ext {
  margin-top: 10px; padding: 8px 10px; font-size: 0.8rem; line-height: 1.5;
  color: var(--risk-limited); background: var(--risk-limited-bg);
  border: 1px solid var(--risk-limited-border); border-radius: 10px;
}
/* ⭐ WHEN A DUTY APPLIES, MARKED INSIDE THE QUOTE (user, 2026-09-10: "highlight inside
   the quote"). Very light orange, the Act's words untouched. ⛔ .at-ob-when (a separate
   box at the top of the panel) is gone — it repeated pieces of the paragraph below it. */
.at-ob-hl { background: #FFEDD5; color: inherit; padding: 0 2px; border-radius: 3px; }
.at-ob-hl-cap { margin: 4px 0 0; font-size: 0.72rem; line-height: 1.35; color: var(--grey-600); }
/* When a duty starts to apply (phase31). Three states, deliberately distinct:
   in force now (neutral), starts later (amber — the surprising one), and no
   single date (grey — the DPIA and Article 86 rows). */
.at-ob-date {
  margin-top: 10px; padding: 8px 10px; border-radius: 10px;
  font-size: 0.8rem; line-height: 1.5; font-weight: 600;
}
.at-ob-datebasis { margin-top: 5px; font-size: 0.75rem; line-height: 1.5; color: var(--grey-600); }
/* Step 1: a use the Act does not catch yet (currently only the two prohibitions
   the Omnibus inserted, which start 2 Dec 2026). Same amber as the tracker's
   future-date chip, so "not yet" reads the same wherever it appears. */
.use-applies {
  display: inline-block; margin-left: 8px; padding: 1px 7px; vertical-align: middle;
  font-size: 0.72rem; font-weight: 700; letter-spacing: 0.02em; white-space: nowrap;
  color: #8a5a00; background: #fff8e6; border: 1px solid #f0d9a0; border-radius: 999px;
}
/* 0.84rem, the same as .at-ob-record (user, 2026-09-10: "the same font type, size as
   any other"). At 0.9rem the provider and tracker-help panels read larger than every
   obligation panel beside them. */
.at-ob-help { margin-top: 12px; font-size: 0.85rem; line-height: 1.5; color: var(--grey-800); }
.at-ob-muted { color: var(--grey-500); font-style: italic; }
.at-ob-fulllabel {
  margin-top: 16px; font-size: 0.72rem; font-weight: 500; letter-spacing: 0.02em;
  text-transform: uppercase; color: var(--grey-500);
  font-family: var(--mono);
}
/* "What to record here" — guidance, not law, so it reads darker than the quoted
   requirement below it and lighter than the explanation above. */
.at-ob-record { margin-top: 5px; font-size: 0.85rem; line-height: 1.5; color: var(--grey-800); }

/* ── "Where this came from": the Step 2 answers behind a card ────────────────
   ⚠ DELIBERATELY NOT .at-ob-quote. That rule's blue left edge marks the Act's own
   words, and these are the CUSTOMER'S answers — the one distinction this whole
   panel family exists to keep. A grey card on a white panel says "your record"
   without borrowing the mark that means "the law". */
.at-src-use {
  margin-top: 8px; padding: 9px 11px;
  background: var(--grey-50, #f8f9fa);
  border: 1px solid var(--grey-200); border-radius: 10px;
}
.at-src-q { font-size: 0.85rem; font-weight: 600; line-height: 1.5; color: var(--grey-900); }
.at-src-meta {
  margin-top: 4px; font-size: 0.72rem; font-weight: 500; letter-spacing: 0.02em;
  text-transform: uppercase; color: var(--grey-500);
  font-family: var(--mono);
}
.at-src-ex {
  display: inline-block; padding: 0 6px;
  color: #8a5a00; background: #fff8e6; border: 1px solid #f0d9a0; border-radius: 999px;
  text-transform: none; letter-spacing: 0;
}
/* Verbatim Act quote inside the explanation panel. */
.at-ob-quote {
  margin-top: 5px;
  padding: 9px 12px;
  border-left: 3px solid var(--eu-blue);
  background: var(--grey-50, #f8f9fa);
  font-size: 0.8rem;
  line-height: 1.5;
  font-style: italic;
  color: var(--grey-700);
  border-radius: 0 8px 8px 0;
}
.at-ob-link {
  display: inline-block;
  margin-top: 12px;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--eu-blue);
}

/* Small screens: one column. The rail drops UNDER the feature panel and stops
   being sticky — a sticky block taller than the viewport cannot be scrolled past. */
@media (max-width: 900px) {
  .at-builder-body { display: block; }
  .at-rail { position: static; margin-top: 18px; }
  .at-feat-nav-inner { max-height: none; }
}

/* ── Reports ── */
/* flex-wrap + gap so "← Back to reports" and "⬇ Download / Print" drop onto two lines
   rather than off the edge of a small phone (found 2026-09-18, phone check at 320px).
   Unconditional, not a media query: on any screen with room for both, space-between
   still puts one at each end and nothing moves. */
.rp-toolbar { display: flex; flex-wrap: wrap; gap: 10px; justify-content: space-between; align-items: center; margin-bottom: 16px; }
/* ⭐ FULL WIDTH LIKE EVERY OTHER SECTION (print check, 2026-10-07: "some parts are a bit
   misaligned"). This and .rpt-attest-section carried 32px of side padding, so the blue bars
   of Scope, Article 25 and Deployer obligations were narrower than those of the other three
   sections and of the header, summary and contents above them. The bar now runs the full
   width; what sits under it takes the same 18px inset as .rpt-sec-body. */
.rpt-actions-section { margin-top: 26px; padding: 0 0 12px; }
.rpt-actions-section > :not(.rpt-sec-head):not(.rpt-sec-sub) { margin-left: 18px; margin-right: 18px; }
/* One card per software → AI feature, matching the tracker screen. The old
   six-column table repeated the software, feature and tier on every duty (or
   left them blank on continuation rows, which printed as a ragged table with
   no visible grouping), and a feature name that is a whole declared use choked
   the other five columns. */
.rpt-at-card {
  margin: 0 0 12px;
  border: 1px solid var(--grey-200);
  border-radius: 12px;
  overflow: hidden;
  page-break-inside: avoid; break-inside: avoid;
}
.rpt-at-card-head {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 12px;
  padding: 9px 12px;
  background: var(--grey-100);
  border-bottom: 1px solid var(--grey-200);
}
.rpt-at-card-names { min-width: 0; }
/* Same order as the tracker screen: the AI feature is the subject, the software
   is the kicker saying where it lives. */
.rpt-at-card-sw {
  font-size: 0.85rem; font-weight: 700; line-height: 1.5; color: var(--grey-900);
}
/* A feature name can be a whole declared use — up to ~170 characters. Here it
   has the width of the page and wraps; in a table cell it squeezed the rest. */
.rpt-at-card-feat { font-size: 0.85rem; font-weight: 700; line-height: 1.5; color: var(--grey-900); }
/* AI literacy is not a tool, so its card has no software above a feature — the
   name is the heading and the sentence under it is the explanation. */
.rpt-at-card-baseline .rpt-at-card-sw { font-size: 0.9rem; letter-spacing: 0; text-transform: none; color: var(--grey-900); }
.rpt-at-card-baseline .rpt-at-card-feat { font-size: 0.8rem; font-weight: 400; color: var(--grey-600); }
.rpt-at-card-head .risk-pill { flex: none; }
/* ⭐ THE PILL IS NEVER BARE HERE (user, 2026-09-07). It sits opposite a software name,
   and unlabelled it reads as a verdict on the software — the claim the rest of this
   report was rewritten to stop making. The label says whose level it is: the declared
   business use. Stacked, and right-aligned under the label, so a long level name
   ("Transparency obligation") cannot squeeze the tool name opposite it. */
/* ── "Carried out by" ────────────────────────────────────────────────────────
   Only on a card that covers a whole declared use. The prohibited card is one per
   PRACTICE now and can span several tools, so the software line reads "Mojipop,
   Notion" and does not say which feature in each did it. Subordinate to the two
   names above it: this answers "by what", where they answer "what". */
.rpt-at-card-by { margin-top: 4px; font-size: 0.8rem; line-height: 1.5; color: var(--grey-700); }
.at-card-by { font-size: 0.8rem; line-height: 1.5; color: var(--grey-700); min-width: 0; }
.rpt-at-card-lvl { flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: 3px; }
.rpt-at-card-lvl .rpt-ans-k { margin-right: 0; white-space: nowrap; }
/* AI literacy is not a risk level — it applies whatever the tools are — so its
   card takes the same blue as the literacy card on the tracker screen rather
   than a green Minimal pill, which would read as a rating it never had. */
.rpt-at-card-baseline { border-left: 3px solid var(--eu-blue); }
.rpt-at-card-baseline .rpt-at-card-head { background: var(--eu-blue-pale); border-bottom-color: var(--eu-blue-light); }
.rpt-at-pill-baseline { background: var(--white); color: var(--eu-blue-dark); border: 1px solid var(--eu-blue-light); }
.rpt-at-duties { width: 100%; border-collapse: collapse; font-size: 0.8rem; }
.rpt-at-duties td { border-top: 1px solid var(--grey-200); padding: 6px 12px; text-align: left; vertical-align: top; }
.rpt-at-duties tr:first-child td { border-top: none; }
.rpt-at-duty { color: var(--grey-800); }
/* The two right-hand columns hold only what they need, so the duty label takes
   the rest. Unwrapped so a printed page keeps each on one line. */
.rpt-applies, .rpt-done { width: 1%; }
/* ⭐ One line (layout review, 2026-09-10): "✓ Complete" and "— Outstanding" broke
   with the mark on one line and the word under it, because width: 1% shrinks the
   column to its narrowest possible content. */
.rpt-done { white-space: nowrap; }
/* ⭐ THE SAME COLUMNS ON EVERY CARD (layout review, 2026-09-10). Sized to their own
   contents, "Applies from" and "Status" sat at a different place on each card —
   "✓ Confirmed (external)" is wider than "✓ Complete" — so they wandered left and
   right down the report. A fixed layout takes its widths from these two columns on
   every table alike: wide enough for "2 December 2027" and "✓ Confirmed (external)",
   and the obligation takes the rest. */
.rpt-at-duties { table-layout: fixed; }
.rpt-at-duties th:nth-child(2), .rpt-at-duties td.rpt-applies { width: 136px; }
.rpt-at-duties th:nth-child(3), .rpt-at-duties td.rpt-done    { width: 196px; }
/* When the duty starts to bind. A future date is emphasised, in-force is not. */
.rpt-applies { white-space: nowrap; color: var(--grey-600); }
.rpt-applies.future { color: #8a5a00; font-weight: 700; }
.rpt-done.yes { color: var(--risk-minimal); font-weight: 700; }
.rpt-done.no { color: var(--risk-limited); font-weight: 700; }
.rpt-ext-badge {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 7px;
  border: 1px solid var(--risk-limited-border);
  border-radius: 999px;
  background: var(--risk-limited-bg);
  color: var(--risk-limited);
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  white-space: nowrap;
  vertical-align: middle;
}
.rpt-ext-note { margin-top: 10px; font-size: 0.8rem; color: var(--grey-800); line-height: 1.5; }

/* Report: risk-category donut */


/* The coverage list. Grouped by initial and run inline, so a big library costs a
   few lines rather than a page — the point is "all of this was looked at", and a
   long vertical table buries that. */

/* Restructured report (2026-07-15): muted/inactive risk, not-assessed, full record */
.risk-pill.inactive { background: var(--grey-200); color: var(--grey-600); box-shadow: none; }
.rpt-record { padding-bottom: 8px; }
/* Transcript report (2026-07-15): inline flags, Act quotes, Step 2, library overview */
.rpt-inline-flag {
  font-size: 0.8rem; line-height: 1.5; color: #8a5a00; background: #fff4e5;
  border-left: 3px solid #f0b64b; padding: 6px 10px; border-radius: 0 8px 8px 0; margin: 6px 0;
}

/* ── §1 — the inventory: what each feature IS ────────────────────────────────
   One block per tool, one row per feature: the vendor's name for it, their account
   of what it does, and the page that account came from. No state, no level — a
   switch position is an answer and belongs in §3, and a level on a catalogue
   feature is the judgement the facts-only cards no longer carry. */
/* ⭐ A TOOL MAY RUN ONTO THE NEXT PAGE; ONE FEATURE MAY NOT (print check, 2026-09-23).
   Kept whole, every tool too tall for what was left of a page jumped to a fresh one,
   and the printed report had pages that were three-quarters empty. */
.rpt-inv-tool { margin-bottom: 16px; }
.rpt-inv-feat { break-inside: avoid; page-break-inside: avoid; }
.rpt-inv-head {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 8px;
  padding-bottom: 6px; border-bottom: 1px solid var(--grey-200);
}
.rpt-inv-tool-name { font-size: 1rem; font-weight: 700; color: var(--eu-blue-dark); font-family: var(--display); }
.rpt-inv-n {
  margin-left: auto; font-size: 0.72rem; font-weight: 700;
  color: var(--grey-600); white-space: nowrap;
}
.rpt-inv-feat { padding: 8px 0 8px 12px; border-left: 2px solid var(--grey-200); margin-top: 8px; }
/* ⭐ LABEL AND VALUE, ONE PAIR PER LINE (user, 2026-09-07: "I like when everything
   has its titles"). A feature was four unlabelled lines and the reader had to tell
   them apart by shape. The label column is fixed so the values line up down the
   whole section — which is what makes it scannable, and the reason the label is not
   simply run inline before each value.
   ⚠ It COLLAPSES on a narrow page rather than squeezing the value into a column of
   three words — the same fault the question rows had. */
.rpt-inv-row { display: flex; gap: 10px; align-items: baseline; padding: 2px 0; }
.rpt-inv-k {
  flex: 0 0 108px; white-space: nowrap;
  font-size: 0.62rem; font-weight: 500; text-transform: uppercase; letter-spacing: 0.02em;
  color: var(--grey-500); line-height: 1.8;
  font-family: var(--mono);
}
.rpt-inv-v { flex: 1 1 auto; min-width: 0; font-size: 0.85rem; line-height: 1.5; color: var(--grey-800); }
.rpt-inv-v strong { font-size: 0.85rem; color: var(--grey-900); }
@media (max-width: 640px) {
  .rpt-inv-row { display: block; }
  .rpt-inv-k { display: block; }
}
/* ⛔ .rpt-inv-feat-what IS DEAD — the description is a labelled row now. */
.rpt-inv-none { margin-top: 8px; font-size: 0.8rem; color: var(--grey-600); font-style: italic; }

/* ── §3 — what the customer SAID about each feature: Step 3, printed ─────────
   ⚠ The same five groups the assessment shows, in the same order, deliberately: the
   customer answered them on that screen, and a document that regrouped them would be
   describing the same record a second way. */
/* ⭐ A CARD PER GROUP, EDGED IN ITS STATE (user, 2026-09-07: "make section 3 more
   visually appealing"). Five headings over five flat lists read as one long list
   with words in it — the reader has to remember which heading they are under. An
   edge that runs the height of the block carries the state down every row in it.
   ⛔ THE COLOURS ARE NOT RISK LEVELS, and must never be read as any: amber marks the
   two states with something left to do (a contradiction, a shrug), green a settled
   answer, grey a feature that is off and owes nothing. Nothing here says anything
   about the Act — the levels live in §2 and §5. */
/* A group may run onto the next page; a single feature row may not (print check,
   2026-09-23: a 12-row group kept whole jumped to a fresh page and left the one
   before it two-thirds empty). */
.rpt-sg-cat {
  margin-top: 16px;
  padding: 12px 14px; border-radius: 12px;
  background: var(--grey-50, #f8f9fa);
  border: 1px solid var(--grey-200); border-left: 4px solid var(--grey-300);
}
.rpt-sg-clash { border-left-color: var(--risk-limited); background: #fffaf2; }
.rpt-sg-named { border-left-color: var(--eu-blue); }
.rpt-sg-on    { border-left-color: var(--risk-minimal); }
.rpt-sg-off   { border-left-color: var(--grey-300); }
.rpt-sg-open  { border-left-color: var(--risk-limited); }
/* The rows sit on white inside the card, so the card is the ground and each feature
   is a thing on it — the same figure/ground rule the tracker rail needed. */
.rpt-sg-rows { margin-top: 2px; }
.rpt-sg-cat-head { display: flex; align-items: baseline; gap: 8px; }
.rpt-sg-cat-name {
  font-size: 0.8rem; font-weight: 500; letter-spacing: 0.02em; text-transform: uppercase;
  color: var(--eu-blue-dark);
  font-family: var(--mono);
}
.rpt-sg-n {
  font-size: 0.72rem; font-weight: 500; color: var(--grey-700);
  background: var(--grey-100); border-radius: 999px; padding: 1px 7px;
  font-family: var(--mono);
}
.rpt-sg-cat-desc { margin: 4px 0 8px; max-width: 78ch; font-size: 0.8rem; line-height: 1.5; color: var(--grey-600); }
.rpt-sg-row {
  break-inside: avoid; page-break-inside: avoid;
  padding: 7px 10px; margin-bottom: 5px;
  background: var(--white);
  border: 1px solid var(--grey-200); border-radius: 8px;
}
.rpt-sg-top { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.rpt-sg-sw {
  flex: 0 0 auto; font-size: 0.72rem; font-weight: 500; letter-spacing: 0.02em;
  text-transform: uppercase; color: var(--grey-500);
  font-family: var(--mono);
}
.rpt-sg-feat { flex: 1 1 220px; min-width: 0; font-size: 0.85rem; line-height: 1.5; color: var(--grey-900); }
/* The use a feature was named for — the one thing a name and a state cannot carry
   between them. Indented under the row it belongs to, never beside it. */
.rpt-sg-uses { margin: 5px 0 0 10px; display: grid; gap: 3px; }
.rpt-sg-use { font-size: 0.8rem; line-height: 1.5; color: var(--grey-700); }
.rpt-sg-use::before { content: '↳ '; color: var(--grey-400); }
/* The switch state, printed only in NAMED IN STEP 2, where the heading is not already
   the answer. A BORDER, not a filled pill: browsers drop background colours out of a
   print by default, and this word is the difference between "we confirmed this is
   running" and "nobody ever established whether it is". It has to survive the paper. */
.rpt-sg-state {
  flex: none; font-size: 0.68rem; font-weight: 700; letter-spacing: 0.02em;
  text-transform: uppercase; font-family: var(--mono); color: var(--grey-700);
  border: 1px solid var(--grey-300); border-radius: 999px; padding: 1px 8px;
}

/* ── The summary at the top of the report (user, 2026-10-07) ─────────────────
   Nine boxes, 3 × 3, above Scope. "More fun, more visible" (user, same day): an icon,
   one big figure and a bar or a badge per box — no sentences.
   ⚠ PRINT: three across fits A4 portrait at the report's width; the block never splits
   over a page; colours print (#reportContent forces print-color-adjust), and every
   bar and dot has a border so it survives a printer that drops backgrounds anyway.
   ⛔ The risk colours appear ONLY on the three use counts — everything else is blue,
   green, amber or grey, so nothing here reads as a rating of the software. */
/* ⚠ A GAP UNDER THE HEADER (print check, 2026-10-07): at margin-top 0 the panel's rounded
   corners sat flush against the header's square ones and read as misaligned. */
.rpt-sum {
  margin: 18px 0 22px; padding: 16px 18px 12px;
  border: 1px solid var(--eu-blue-light); border-radius: 16px;
  background: linear-gradient(160deg, var(--eu-blue-pale), var(--white) 65%);
  break-inside: avoid; page-break-inside: avoid;
}
.rpt-sum-title {
  font-size: 0.8rem; font-weight: 500; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--eu-blue); margin-bottom: 10px; font-family: var(--mono);
}
.rpt-sum-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
.rpt-sum-box {
  min-width: 0; padding: 12px 14px 13px; border-radius: 12px;
  background: var(--white); border: 1px solid var(--grey-200);
  box-shadow: 0 1px 2px rgba(16, 24, 64, 0.05);
  display: flex; flex-direction: column; align-items: flex-start; gap: 6px;
  break-inside: avoid; page-break-inside: avoid;
}
.rpt-sum-open { border-color: var(--risk-limited-border); background: #fffaf2; }
.rpt-sum-head { display: flex; align-items: center; gap: 8px; }
.rpt-sum-ico {
  width: 28px; height: 28px; border-radius: 8px; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--eu-blue-light); color: var(--eu-blue);
}
.rpt-sum-ico svg { width: 17px; height: 17px; }
.rpt-sum-open .rpt-sum-ico { background: var(--risk-limited-bg); color: var(--risk-limited); }
.rpt-sum-k {
  font-size: 0.66rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--grey-600); font-family: var(--mono);
}
.rpt-sum-n {
  font-family: var(--display); font-size: 2.4rem; font-weight: 800; line-height: 1;
  color: var(--eu-blue-dark); letter-spacing: -0.03em;
}
.rpt-sum-of { font-size: 1.3rem; font-weight: 700; color: var(--grey-400); letter-spacing: 0; }
.rpt-sum-n.rpt-sum-warn { color: var(--risk-limited); }
.rpt-sum-n.rpt-sum-good { color: var(--risk-minimal); }
.rpt-sum-word { font-family: var(--display); font-size: 1.3rem; font-weight: 800; line-height: 1.15; color: var(--eu-blue-dark); }
.rpt-sum-id { font-family: var(--mono); font-size: 0.7rem; color: var(--grey-500); overflow-wrap: anywhere; }

.rpt-sum-badge {
  display: inline-block; font-size: 0.7rem; font-weight: 700; line-height: 1.3;
  padding: 3px 9px; border-radius: 999px; border: 1px solid transparent;
}
.rpt-sum-badge-blue  { background: var(--eu-blue-light); color: var(--eu-blue-dark); border-color: var(--eu-blue-light); }
.rpt-sum-badge-green { background: var(--risk-minimal-bg); color: var(--risk-minimal); border-color: var(--risk-minimal-border); }
.rpt-sum-badge-warn  { background: var(--risk-limited-bg); color: var(--risk-limited); border-color: var(--risk-limited-border); }
.rpt-sum-badge-grey  { background: var(--grey-100); color: var(--grey-700); border-color: var(--grey-200); }

.rpt-sum-bar {
  width: 100%; height: 10px; border-radius: 999px; overflow: hidden;
  background: var(--grey-100); border: 1px solid var(--grey-200);
}
.rpt-sum-bar span { display: block; height: 100%; background: var(--risk-minimal); }

.rpt-sum-chips { display: flex; flex-wrap: wrap; gap: 4px; }
.rpt-sum-chip {
  font-size: 0.7rem; font-weight: 600; color: var(--eu-blue-dark); background: var(--eu-blue-pale);
  border: 1px solid var(--eu-blue-light); border-radius: 999px; padding: 1px 8px;
  white-space: nowrap; max-width: 100%; overflow: hidden; text-overflow: ellipsis;
}
.rpt-sum-chip-more { color: var(--grey-600); background: var(--grey-100); border-color: var(--grey-200); }

.rpt-sum-stack {
  display: flex; width: 100%; height: 10px; border-radius: 999px; overflow: hidden;
  border: 1px solid var(--grey-200); background: var(--grey-100);
}
.rpt-sum-seg + .rpt-sum-seg { border-left: 2px solid var(--white); }
.rpt-sum-seg-on, .rpt-sum-dot-on { background: var(--risk-minimal); }
.rpt-sum-seg-off, .rpt-sum-dot-off { background: var(--grey-300); }
.rpt-sum-seg-notsure, .rpt-sum-dot-notsure { background: var(--risk-limited); }
.rpt-sum-legend { font-size: 0.7rem; color: var(--grey-600); display: flex; align-items: center; flex-wrap: wrap; gap: 3px 4px; }
.rpt-sum-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; margin-left: 4px; border: 1px solid rgba(0,0,0,0.12); }
.rpt-sum-dot:first-child { margin-left: 0; }

/* The three use counts — the one place the risk colours appear.
   ⚠ THREE ROWS, NOT THREE COLUMNS (2026-10-07): at A4 width a third of a third of the page
   is ~60px, and "Transparency" broke mid-word. A row gives the word the box's full width. */
.rpt-sum-tcs { display: grid; gap: 5px; width: 100%; }
.rpt-sum-tc {
  display: flex; align-items: center; gap: 10px; min-width: 0;
  padding: 3px 10px; border-radius: 8px; border: 1px solid transparent;
}
.rpt-sum-tcn { font-family: var(--display); font-size: 1.3rem; font-weight: 800; line-height: 1.1; min-width: 1.2em; text-align: center; }
.rpt-sum-tcl { font-size: 0.72rem; font-weight: 700; }
.rpt-sum-tc-Unacceptable { background: var(--risk-unacceptable-bg); color: var(--risk-unacceptable); border-color: var(--risk-unacceptable-border); }
.rpt-sum-tc-High         { background: var(--risk-high-bg); color: var(--risk-high); border-color: var(--risk-high-border); }
.rpt-sum-tc-Limited      { background: var(--risk-limited-bg); color: var(--risk-limited); border-color: var(--risk-limited-border); }
.rpt-sum-tc.rpt-sum-zero { background: var(--grey-50); color: var(--grey-400); border-color: var(--grey-200); }

/* "Still open": one row per kind of unfinished item, the count on the right. */
.rpt-sum-rows { width: 100%; display: grid; gap: 2px; }
.rpt-sum-row { display: flex; justify-content: space-between; gap: 8px; font-size: 0.72rem; color: var(--grey-500); }
.rpt-sum-row b { font-weight: 700; color: var(--grey-400); }
.rpt-sum-row-on { color: var(--grey-800); }
.rpt-sum-row-on b { color: var(--risk-limited); }
.rpt-sum-check {
  width: 36px; height: 36px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center;
  font-size: 1.2rem; font-weight: 800; color: var(--white); background: var(--risk-minimal);
  border: 1px solid var(--risk-minimal);
}
.rpt-sum-check-no { background: var(--risk-limited); border-color: var(--risk-limited); }

.rpt-sum-note { margin: 10px 2px 0; font-size: 0.7rem; line-height: 1.5; color: var(--grey-500); }
@media (max-width: 900px) { .rpt-sum-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .rpt-sum-grid { grid-template-columns: minmax(0, 1fr); } }
/* ⭐ ON PAPER, PAGE 1 IS THE COVER: header + summary. The contents box never fitted under the
   summary and jumped to page 2 anyway, leaving half a page empty by accident; breaking here
   makes the same layout deliberate (print check, 2026-10-07). */
@media print {
  .rpt-sum-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .rpt-sum-box { box-shadow: none; }
  .rpt-sum { break-after: page; page-break-after: always; }
}

/* ── Software assessed: the list before the detail (user, 2026-10-07) ─────────
   One row per tool, so the whole inventory is seen before the first tool's features. */
.rpt-swl { width: 100%; border-collapse: collapse; margin: 4px 0 20px; font-size: 0.82rem; }
.rpt-swl th {
  text-align: left; font-size: 0.62rem; font-weight: 500; text-transform: uppercase; letter-spacing: 0.03em;
  color: var(--grey-500); font-family: var(--mono); padding: 6px 8px; border-bottom: 2px solid var(--eu-blue-light);
}
.rpt-swl td { padding: 7px 8px; border-bottom: 1px solid var(--grey-200); color: var(--grey-700); vertical-align: baseline; }
.rpt-swl tbody tr:nth-child(even) td { background: var(--eu-blue-pale); }
.rpt-swl tr { break-inside: avoid; page-break-inside: avoid; }
.rpt-swl-name { font-weight: 700; color: var(--eu-blue-dark) !important; }
.rpt-swl-n { font-weight: 700; color: var(--grey-900) !important; }
@media (max-width: 560px) { .rpt-swl th:nth-child(2), .rpt-swl td:nth-child(2) { display: none; } }

/* Completeness chips on a tool in §1 — quiet, because they are facts about the
   record. ⚠ "nothing established" is the one that must NOT read as a clean result. */
.rpt-sw-tag-quiet { background: var(--grey-100); color: var(--grey-600); border-color: var(--grey-200); }
.rpt-sw-tag-open { background: var(--risk-limited-bg); color: var(--risk-limited); border-color: var(--risk-limited-border); }

/* Report v3 (2026-07-15) — visual pass: section headers, blue answers, act blocks, cards */
.rpt-sec-head {
  display: flex; align-items: center; gap: 10px;
  background: var(--eu-blue); color: #fff;
  padding: 11px 18px; border-radius: 10px; margin: 28px 0 0;
}
.rpt-sec-head h2 { font-size: 1.1rem; font-weight: 700; margin: 0; color: #fff; font-family: var(--display); letter-spacing: -0.01em; }
.rpt-sec-num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; border-radius: 50%;
  background: #fff; color: var(--eu-blue); font-weight: 700; font-size: 0.85rem;
}
.rpt-sec-sub { font-size: 0.85rem; color: var(--grey-600); line-height: 1.5; padding: 10px 18px 2px; margin: 0; }
/* ⚠ A SECOND STANDFIRST MUST NOT RE-PAY THE TOP PADDING. Section 2 carries two of
   these now, and the 10px above each one put a paragraph break where the first
   paragraph's own line spacing already sat — the pair read as two separate
   introductions rather than one in two sentences. */
.rpt-sec-sub + .rpt-sec-sub { padding-top: 6px; }
.rpt-sec-body { padding: 8px 18px 6px; }

/* ⛔ .risk-band-* removed 2026-10-07 — its only user was the "Highest risk level declared" line. */

/* Step 1 — question rows: question left, answer right */
.rpt-q { padding: 10px 0; border-bottom: 1px solid var(--grey-200); }
.rpt-q:last-child { border-bottom: none; }
.rpt-q-ns { background: #fffaf2; border-radius: 10px; padding: 10px 12px; margin: 4px 0; border-bottom: none; }
/* ⛔⛔ THE ANSWER COLUMN IS BOUNDED (user, 2026-09-07: the question "is limited by 3
   words per line or so"). It was `1fr auto`, and `auto` means max-content: the answer
   side took whatever width its badges needed and the question made do with the rest.
   That was fine while an answer was "Yes" and one pill. An exempt row now carries
   five things — Yes · exemption applies · the provision asked about · its level · so
   this use is · the outcome — and on those rows the question was crushed into a
   three-word column while the badges sat on one long line beside it.
   ⚠ minmax(0, …) ON BOTH, and flex-wrap on the badges: without the wrap the answer
   side cannot use the width it is given and overflows instead of stacking; without
   minmax(0) a grid item still refuses to shrink below its longest word. */
.rpt-q-main {
  display: grid;
  /* ⭐ THE ANSWER COLUMN IS CAPPED, NOT PROPORTIONAL (user, 2026-09-07: "stretch …
     a bit further to the right as there is enough space and might make the report
     shorter"). At 3fr/2fr the answer took two fifths of every row whatever it held —
     and on most rows it holds "YOUR ANSWER · No". Its widest case is fixed and known:
     the label, plus Yes, plus "exemption applies", about 270px. Cap it there and the
     question keeps everything else, which on a wide page is roughly a third more
     width and correspondingly fewer lines down the whole section.
     ⚠ THE FLOOR MATTERS AS MUCH AS THE CEILING. Below 180px the badges start stacking
     one per line and the row grows taller than the width it saved. */
  grid-template-columns: minmax(0, 1fr) clamp(180px, 30%, 280px);
  gap: 16px; align-items: start;
}
/* ⭐ THE QUESTION IS THE HEADING OF ITS OWN ROW (user, 2026-09-07, on a screenshot).
   Everything under it — the exemption block, the quote, the citation — had grown
   louder than the thing they were all about: the exemption headed itself in bold
   uppercase blue, and the citation printed in blue 800-weight, so a reader scanning
   the page met the footnotes before the question. This is the one line that has to
   carry, so it is a little larger and a little heavier, and the rest steps back. */
.rpt-q-text { font-size: 0.9rem; font-weight: 600; line-height: 1.5; color: var(--grey-900); }
/* ⭐ ONE FACT PER LINE, right-aligned under the answer (user, 2026-09-07). The badges
   used to share one wrapping row, so where the line broke — and therefore which
   badges appeared to belong together — depended on the width available. Explicit
   lines pair them the same way at every size. */
.rpt-q-ans { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; min-width: 0; }
.rpt-ans-line { display: flex; align-items: center; justify-content: flex-end; flex-wrap: wrap; gap: 6px; }
/* The label before a badge must not be orphaned from the badge it introduces —
   "changes to" alone at the end of a line reads as an unfinished sentence. */
.rpt-q-ans .rpt-ans-k { white-space: nowrap; }
/* ⚠ NOT grey-600 (user: "This is barely to see"). Which tool and which feature is
   an ANSWER the customer gave, not a caption — it belongs with the other answers in
   weight, and the label beside it already marks it as secondary. */
.rpt-q-tools, .rpt-q-note { font-size: 0.8rem; color: var(--grey-800); line-height: 1.5; margin-top: 6px; }
.rpt-q-note { font-style: italic; }
/* ⭐ UNDERLINED (user, 2026-09-07). It is the only line in a question row that names
   the customer's own software, and it was getting lost between the question above it
   and the exemption block below — both of which are longer and carry more weight.
   ⚠ text-underline-offset keeps the rule clear of the descenders in a long feature
   name; without it "Smart summaries — summarises…" strikes through its own tails.
   ⛔ The NOTE beside it is deliberately left alone: it is the deployer's own sentence,
   already marked out by the italic, and underlining both would flatten the
   distinction between what the record says and what the customer said about it. */
.rpt-q-tools { text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }

/* ⛔ THE SAME CRUSH AS STEP 2, ON SCREEN ONLY (found 2026-09-18, first phone-width check).
   The answer column has a 180px floor — right, and deliberate, on a page wide enough to
   have 180px to spare. On a 390px phone it left the question about 114px: one word a line,
   for every question in the section.
   Below 560px the answer goes UNDER the question and reads from the left, because it is no
   longer a column beside anything — the right-alignment of 2026-09-07 pairs each label with
   its badge across a gap that only exists on a wide page.
   ⚠ SCREEN ONLY. Print is laid out at paper width (~794px), so this never applies to the
   printed report and the two-column rows the user checked on 17 Sept are untouched. */
@media (max-width: 560px) {
  .rpt-q-main { grid-template-columns: minmax(0, 1fr); gap: 8px; }
  .rpt-q-ans { align-items: flex-start; }
  .rpt-ans-line { justify-content: flex-start; }
}

/* Answer badge — blue and always visible on white (neutral: same for Yes/No) */
.rpt-ans-badge { display: inline-block; font-size: 0.75rem; font-weight: 700; padding: 3px 12px; border-radius: 999px; background: var(--eu-blue); color: #fff; border: none; }
.rpt-ans-ns { border-color: #f0c98a; background: var(--risk-limited); color: #fff; }
/* ⭐ A "NO" IS QUIETER THAN A "YES" (layout review, 2026-09-10: "Yes" should stand out).
   Both were the same filled blue pill — and on paper both printed pale, so a Yes was
   as easy to miss as the twenty Nos around it. A Yes is what the rest of the report
   follows from; a No is part of the record, and reads like one. Not grey-400 text: it
   is still an answer the customer gave, and has to be legible. */
.rpt-ans-no { background: var(--white); color: var(--grey-700); border: 1px solid var(--grey-300); }
/* Not a risk colour: an exemption is neither a warning nor a clean bill, it is a
   position the deployer has taken and the Act's words for it. */
.rpt-ans-ex { border-color: var(--eu-blue); background: var(--eu-blue-dark); color: #fff; }
/* ⭐ WHAT THE EXEMPTION LEAVES — the last badge on an exempt row, and the one the
   reader should finish on.
   ⚠ IT WEARS .risk-pill, NOT .rpt-ans-badge (user, 2026-09-07: "for out of scope can
   you use the same font style as for other risk"). It answers the same question every
   risk pill in this document answers — where does this land — so it has to be read as
   one of them at a glance, not as a different kind of mark that happens to sit in the
   same row. Only the colour differs, and it differs on purpose: this is the one
   outcome that means nothing is owed.
   ⚠ Its words come from the exemption's own outcome_short in QUESTIONS_DB, never
   from here — "Out of scope", or "Not prohibited" for an Article 5 carve-out. */
.rpt-out-pill {
  background: var(--risk-minimal-bg); color: var(--risk-minimal);
  border: 1px solid var(--risk-minimal-border);
}
.rpt-ans-na { background: var(--grey-300); color: var(--grey-700); }

/* The exemption, printed under the question it answers: what is left out, the
   Act's own wording, and what it does to the result. */
/* ⭐ The tint reaches out into the gutter, the TEXT stays on the column (layout
   review, 2026-09-10): its 12px padding pushed an exempt question right of every
   question around it. A negative margin of the same size puts it back in line. */
.rpt-q-ex-row { background: var(--eu-blue-pale); border-radius: 10px; padding: 10px 12px; margin: 4px -12px; border-bottom: none; }
.rpt-q-ex { margin-top: 8px; border-left: 3px solid var(--eu-blue); padding: 2px 0 2px 12px; }
/* ⛔ NO LONGER BOLD UPPERCASE BLUE. It is a sub-heading inside a footnote to the
   question above it, and it was set louder than the question itself. */
.rpt-q-ex-head { font-size: 0.8rem; font-weight: 700; color: var(--grey-800); }
.rpt-q-ex-what { font-size: 0.8rem; line-height: 1.5; color: var(--grey-800); margin-top: 3px; }
.rpt-q-ex-quote { font-size: 0.8rem; line-height: 1.5; color: var(--grey-700); font-style: italic; margin: 6px 0 0; padding-left: 10px; border-left: 2px solid var(--grey-300); }
/* Where an exemption is quoted from a provision OTHER than the question's own —
   B11 is quoted from Article 6(1a), inserted by the Omnibus. */
.rpt-q-ex-ref { font-size: 0.72rem; color: var(--grey-600); margin-top: 4px; padding-left: 10px; }
.rpt-q-ex-foot { font-size: 0.8rem; font-weight: 600; color: var(--grey-800); margin-top: 6px; }

/* Act quote block — clearly boxed off from the question */
/* A citation in the body: the reference, and where the wording is. Deliberately
   quiet — it is a pointer, not the thing. The wording lives once, in the appendix. */
/* The citation on an obligation row in §5 — the same shape as the one under a
   question in §2 (.rpt-act-cite), because they point into the same appendix and a
   reader should not have to learn two. Quiet: it is a pointer, not the thing. */
.rpt-at-duty-cite { margin-top: 4px; font-size: 0.68rem; line-height: 1.5; color: var(--grey-600); }
.rpt-at-duty-cite-n {
  display: inline-block; margin-left: 6px; padding: 0 6px;
  font-size: 0.62rem; font-weight: 500; letter-spacing: 0.02em;
  color: var(--grey-600); background: var(--grey-100);
  border: 1px solid var(--grey-200); border-radius: 999px; white-space: nowrap;
  font-family: var(--mono);
}

.rpt-act-cite {
  /* ⛔ NOT BLUE AND NOT BOLD (user, 2026-09-07: it was "in thick blue font making it
     the main point"). The comment above already called it a pointer; the styling said
     otherwise. Grey and regular — findable when looked for, silent when not. */
  margin: 6px 0 2px; font-size: 0.72rem; font-weight: 500;
  color: var(--grey-600); display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
}
.rpt-act-cite-n {
  font-weight: 500; font-size: 0.66rem; letter-spacing: 0.02em;
  color: var(--grey-600); background: var(--grey-100);
  border: 1px solid var(--grey-200);
  border-radius: 999px; padding: 1px 7px; white-space: nowrap;
  font-family: var(--mono);
}

/* The appendix: every provision, once, verbatim, in the Act's own order. */
/* Full width like the numbered sections (print check, 2026-10-07); its sub and body carry the 18px inset. */
.rpt-appendix-section { margin-top: 26px; padding: 0 0 8px; page-break-before: always; }
.rpt-prov {
  margin: 0 0 14px; padding: 10px 12px;
  border: 1px solid var(--grey-200); border-left: 3px solid var(--eu-blue);
  border-radius: 0 10px 10px 0; background: var(--eu-blue-pale);
  page-break-inside: avoid; break-inside: avoid;
}
.rpt-prov-head { margin-bottom: 5px; }
.rpt-prov-ref { font-size: 0.8rem; font-weight: 700; color: var(--eu-blue-dark); }
.rpt-prov-text {
  margin: 0; padding: 0; font-size: 0.8rem; line-height: 1.65;
  color: var(--grey-800); font-style: italic;
}
.rpt-prov-link { margin-top: 5px; font-size: 0.72rem; }
.rpt-prov-link a { color: var(--eu-blue); font-weight: 700; }

/* The deployer's own account of HOW a feature's duties are met. The ticks say a
   duty is done; this is the only place the report says how, so it reads as
   testimony — indented, quoted, attributed to the feature above it. */
/* Now the foot of the card whose duties it explains, rather than a floating
   quote in a table row — so it takes the card's full width and no border of
   its own beyond the rule separating it from the duties. */
.rpt-at-note {
  margin: 0; padding: 8px 12px;
  border-top: 1px solid var(--grey-200);
  background: var(--eu-blue-pale);
  page-break-inside: avoid; break-inside: avoid;
}
.rpt-at-note-label {
  font-size: 0.72rem; font-weight: 500; text-transform: uppercase; letter-spacing: 0.02em;
  color: var(--eu-blue); margin-bottom: 4px;
  font-family: var(--mono);
}
.rpt-at-note-body { font-size: 0.8rem; line-height: 1.5; color: var(--grey-800); white-space: pre-wrap; }

/* Article 5 declaration callout */
/* Provenance for a description: whose words, when they were read, and the page.
   Quieter than the description it backs — it is there to be checked, not read. */
.src-line { font-size: 0.72rem; color: var(--grey-500); line-height: 1.5; margin: 2px 0 6px; }
.src-line a { color: var(--grey-600); text-decoration: underline; text-underline-offset: 2px; }

/* RA builder — "does this tool use AI?" for unrecognised tools (phase26).
   Neutral buttons; selected = blue (no verdict colours on an answer). */
.ai-status { margin-top: 12px; }
.ai-status-q { font-weight: 700; font-size: 0.9rem; margin-bottom: 8px; }
.ai-status-btns { display: flex; flex-direction: column; gap: 8px; }

/* Print: strip the app chrome, show only the report */
@media print {
  .dash-sidebar, .dash-topbar, .no-print, .rp-toolbar, .dash-footer,
  #dashMismatchNotice { display: none !important; }
  .dash-app { display: block !important; }
  .dash-main { display: block !important; }
  .dash-content { padding: 0 !important; max-width: none !important; }
  #reportContent { box-shadow: none !important; border: none !important; }

  .rpt-actions-section    { page-break-before: always; }
  .report-disclaimer      { page-break-before: always; }


  /* On paper the href is invisible, so the line prints the page it points at.
     The link text is already the host — this adds the rest of the path. */
  .src-line a::after { content: " (" attr(href) ")"; word-break: break-all; }
  .src-line a { text-decoration: none; }

  /* ⭐ THE REPORT PRINTS IN ITS OWN COLOURS (layout review, 2026-09-10). Browsers drop
     backgrounds on paper unless told not to, so the blue section bars vanished and
     their white headings printed a pale grey that read as disabled — and the pale
     blue behind an exempt question went too, leaving it looking mis-indented. */
  #reportContent, #reportContent * { -webkit-print-color-adjust: exact; print-color-adjust: exact; }

  /* A section heading never ends a page on its own — page 1 finished on
     "1 Your software" with the software starting on page 2. */
  /* ⭐ AND THE BAR ITSELF IS NEVER SPLIT (print check, 2026-09-17). On the printed report
     the section-3 bar began in the last few millimetres of page 13 and finished on page 14,
     cutting its number circle in half: break-after only keeps the heading with what FOLLOWS
     it, and says nothing about the heading being fragmented. */
  .rpt-sec-head, .rpt-sec-sub { break-after: avoid; page-break-after: avoid; }
  .rpt-sec-head { break-inside: avoid; page-break-inside: avoid; }

  /* ⭐ A TALL OBLIGATION CARD MAY CONTINUE ONTO THE NEXT PAGE (layout review,
     2026-09-10). Kept whole, a high-risk card with ten duties could not fit below
     the AI-literacy card and left page 17 almost empty. It still never splits its
     head from its first row, nor any single duty. */
  .rpt-at-card { break-inside: auto; page-break-inside: auto; }
  .rpt-at-card-head, .rpt-at-when { break-after: avoid; page-break-after: avoid; }
  .rpt-at-duties tr { break-inside: avoid; page-break-inside: avoid; }

  /* ⭐ NOTHING SPLITS IN A WAY THAT STRANDS HALF OF IT (print check, 2026-09-23):
     · a tool's name line stays with its first feature;
     · a question never leaves its "QUESTION … YOUR ANSWER" line at the foot of one
       page and the question itself on the next;
     · the short note that closes the obligations moves whole — two of its lines
       had ended up alone on a page. */
  .rpt-inv-head { break-after: avoid; page-break-after: avoid; }
  .rpt-q { break-inside: avoid; page-break-inside: avoid; }
  .rpt-ext-note { break-inside: avoid; page-break-inside: avoid; }
  /* …and a group's title and description stay with its first row, and a section's
     one-line introduction is never cut in half. */
  .rpt-sg-cat-head, .rpt-sg-cat-desc { break-after: avoid; page-break-after: avoid; }
  .rpt-sec-sub { break-inside: avoid; page-break-inside: avoid; }

  /* ⭐ break-after: avoid IS NOT ENOUGH IN CHROME (print check, 2026-10-09). The rules above
     were already there, and still four headings printed as the last line of a page with
     their content on the next: the "Biometrics", "Employment & managing workers" and
     "Emotion or biometric categorisation" area headings in section 3, and the Asana Smart
     chat card in section 4 (head + "Obligations" + column titles, first row overleaf).
     The fix that holds: an invisible, unbreakable block hangs below the heading (or at the
     top of the card) and takes no room — its negative margin cancels its height — so it
     only matters at a page foot, where it cannot fit and carries the heading over with it.
     Height = card head with its first duty. Re-print 2026-10-09: this held for the card,
     but NOT for the area headings (a spacer inside the h4 was ignored) — those are now
     wrapped with their first question in .rpt-area-keep by the report builder. */
  .rpt-area-keep { break-inside: avoid; page-break-inside: avoid; }
  /* Re-print 2, 2026-10-09: the "High-risk uses" block title then ended page 4 alone. Same
     hanging block as the card — it holds there. */
  #reportContent .use-block::before,
  .rpt-at-card::before {
    content: ""; display: block; height: 300px; margin-bottom: -300px;
    break-inside: avoid; page-break-inside: avoid;
  }
}

/* ── My Account ── */
/* Fields run the full width of the card so the separators between sections
   line up; the controls inside them stay narrow. */
.dash-account-field { margin-bottom: 18px; }
.dash-account-field > .input { max-width: 460px; }
.dash-account-field .scope-options,
.dash-account-field .entity-options,
.dash-account-field .entity-help { max-width: 640px; }

/* Shown when the organisation type on screen differs from the one the page was
   opened with. Same treatment as the matching note on the tracker itself
   (.at-entity-note) — this is the same fact told at the other end. */
.acc-type-change {
  margin-top: 10px;
  max-width: 640px;
  font-size: 0.85rem;
  line-height: 1.5;
  color: var(--grey-700);
  background: var(--risk-limited-bg);
  border: 1px solid var(--risk-limited-border);
  border-radius: 10px;
  padding: 10px 12px;
}

/* Rule between fields inside one card. */
.dash-account-field + .dash-account-field {
  border-top: 1px solid var(--grey-200);
  padding-top: 18px;
}
.dash-account-card .dash-account-field:last-of-type { margin-bottom: 0; }
/* The page is compact now: the options sit closer together than on the landing page. */
.acc-business .scope-options, .acc-business .entity-options { gap: 6px; }
.acc-business .scope-option { padding: 9px 14px; }
.acc-business .entity-option { padding: 9px 12px; }

.dash-account-value {
  padding: 4px 0;
  font-size: 0.95rem;
  color: var(--grey-800);
}

.dash-account-saved {
  margin-top: 6px;
  color: var(--risk-minimal);
  font-size: 0.85rem;
  font-weight: 600;
}

.dash-account-recovery {
  margin: 4px 0 10px;
  padding: 10px 12px;
  background: var(--eu-blue-light);
  border-radius: 10px;
  color: var(--eu-blue-dark);
  font-size: 0.85rem;
  font-weight: 600;
}

.dash-billing-note {
  margin: 2px 0 12px;
  font-size: 0.85rem;
  line-height: 1.5;
  color: var(--grey-600);
}
.dash-billing-actions {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

/* ── App dialog (custom confirm/alert) ── */
.dash-modal {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  justify-content: center;
  padding: 20px;
  overflow-y: auto;
}
.dash-modal.hidden { display: none; }
.dash-modal-backdrop { position: fixed; inset: 0; background: rgba(11, 27, 63, 0.45); backdrop-filter: blur(2px); }
.dash-modal-box {
  position: relative;
  margin: auto;
  max-height: calc(100vh - 40px);
  overflow-y: auto;
  background: var(--white);
  border-radius: 18px;
  box-shadow: 0 30px 70px -20px rgba(11, 27, 63, 0.45);
  width: min(460px, 92vw);
  padding: 28px 28px 24px;
}
.dash-modal-close {
  position: absolute;
  top: 12px;
  right: 12px;
  border: none;
  background: none;
  font-size: 1rem;
  color: var(--grey-400);
  cursor: pointer;
  padding: 0;
  border-radius: 999px;
  line-height: 1;
  width: 30px;
  height: 30px;
  transition: background 0.15s, color 0.15s;
}
.dash-modal-close:hover { background: var(--grey-100); color: var(--grey-800); }
.dash-modal-title { font-size: 1.25rem; font-weight: 700; color: var(--grey-900); margin-bottom: 10px; padding-right: 24px; font-family: var(--display); letter-spacing: -0.01em; }
.dash-modal-msg { font-size: 0.9rem; color: var(--grey-800); line-height: 1.5; white-space: pre-line; }
.dash-modal-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 24px; }
/* "Confirming your payment…" on the return from Stripe — small, centred, no button. */
.dash-modal-box.pay-confirming-box { width: min(300px, 92vw); text-align: center; padding: 26px 24px 22px; }
.pay-confirming-spin {
  display: inline-block; width: 28px; height: 28px; border-radius: 50%;
  border: 3px solid var(--grey-200); border-top-color: var(--eu-blue);
  animation: payConfirmingSpin 0.9s linear infinite;
}
@keyframes payConfirmingSpin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .pay-confirming-spin { animation-duration: 2.4s; } }
.pay-confirming-text { margin-top: 12px; font-size: 0.95rem; font-weight: 600; color: var(--grey-900); }

.btn-danger { background: var(--risk-high); color: #fff; }
.btn-danger:hover { background: var(--risk-high-border); }

/* ── Loading splash ── */
.dash-loading {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--grey-100);
  color: var(--grey-600);
  font-size: 0.95rem;
  z-index: 100;
}
.dash-loading.hidden { display: none; }

/* ── Responsive ── */
@media (max-width: 860px) {
  .dash-app { flex-direction: column; }
  .dash-sidebar {
    width: 100%;
    height: auto;
    position: static;
    border-right: 0;
    border-bottom: 1px solid var(--grey-200);
  }
  .dash-nav {
    flex-direction: row;
    flex-wrap: wrap;
    padding: 8px 10px;
  }
  .dash-nav-item { padding: 8px 10px; font-size: 0.85rem; }
  .dash-nav-icon { display: none; }
  .dash-sidebar-foot { display: none; }
  .dash-content { padding: 18px 16px 48px; }
  .dash-topbar { padding: 12px 16px; }
  /* ⛔ 128px OF STICKY HEADER ON EVERY PAGE (found 2026-09-18, first phone-width check).
     Title, separator, business name, type pill and the email all competed for one row,
     so the title wrapped inside a 113px box, the name went under it and the pill under
     that — a third of a phone screen, pinned, before any content.
     Two rows now: the page title with Sign out beside it, the business under them. The
     EMAIL GOES, exactly as it already does on the landing page's own bar below 860px
     (site.css) — it is on My Account, and it was the widest thing here. ~64px. */
  .dash-topbar {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    column-gap: 12px;
    row-gap: 2px;
    min-height: 0;
  }
  .dash-topbar-user .dash-user-email { display: none; }
  /* ⛔ THE ONE LINE THAT MADE EVERY DASHBOARD PAGE SCROLL SIDEWAYS (found 2026-09-18,
     first phone-width check). The address line is 451px wide and was set never to
     wrap, so on anything under about 510px the DOCUMENT grew wider than the screen.
     Worse than the scrollbar: a modal is centred on the document, not the window, so
     the confirm dialog's OK button and the feedback window's Send button hung off the
     right edge with it. It wraps below 860px now, and sits with the rest of the footer
     instead of being pushed to the right of a row it no longer shares. */
  .dash-footer-copy { white-space: normal; margin-left: 0; }
}

/* ═══════════════════════════════════════════════
   HOW IT WORKS — guide page
   ═══════════════════════════════════════════════ */
.guide-h { font-size: 1.15rem; font-weight: 700; color: var(--grey-900); margin: 0 0 12px; font-family: var(--display); letter-spacing: -0.01em; }
.guide-h4 { font-size: 1.05rem; font-weight: 700; color: var(--grey-900); margin: 34px 0 22px; font-family: var(--display); letter-spacing: -0.01em; }
.guide-p { font-size: 0.9rem; color: var(--grey-800); line-height: 1.65; margin: 0 0 12px; }


.guide-list { margin: 0 0 12px; padding-left: 18px; }
.guide-list li { font-size: 0.9rem; color: var(--grey-800); line-height: 1.5; margin-bottom: 6px; }
.guide-list-tight li { margin-bottom: 3px; }

/* A date qualifier inside a duty list — the two Article 26 duties whose start is
   not the shared one. Quiet, because it qualifies the duty rather than competing
   with it, and matching the <em> notes already used in these lists.
   ⛔ NO white-space: nowrap (removed 2026-09-18). It was there to keep a date on one
   line, and instead it set a floor under everything around it: the longest of these
   notes is 293px, so the card could never be narrower than that. On a small phone it
   pushed the whole guide sideways; at about 1280px, where the two card columns are
   their most awkward width, it hung 13px out past the card's own right edge. It wraps
   like the prose it sits in now, at every width. */
.guide-note-inline { font-style: italic; color: var(--eu-blue); }

/* The step number beside a heading in "The four steps" — the same filled blue disc
   the four-step image uses, so the heading and the picture above it read as one thing. */
.guide-stepn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; margin-right: 8px; vertical-align: baseline;
  border-radius: 50%; background: var(--eu-blue); color: #fff;
  font-size: 0.72rem; font-weight: 700; line-height: 1;
}

/* A cross-reference from one guide tab to another. Reads as a link because it is
   one — it used to be a tab name in bold, which left the reader to go and find it. */
.guide-xref { color: var(--eu-blue); font-weight: 700; text-decoration: underline; text-underline-offset: 2px; }
.guide-xref:hover { color: var(--eu-blue-dark); }

.guide-note {
  font-size: 0.85rem; color: var(--grey-800); line-height: 1.5;
  background: var(--eu-blue-light); border-left: 3px solid var(--eu-blue);
  border-radius: 0 10px 10px 0; padding: 10px 14px; margin: 12px 0 0;
}

/* What holds an assessment's lock open, in The four steps (2026-09-14): the two
   kinds of blocker as two cards side by side, stacking on a narrow screen, then
   "Not sure" in green because it is the one thing that never blocks. */
.guide-lock { margin: 12px 0 0; }
.guide-lock-lead { font-size: 0.9rem; color: var(--grey-800); line-height: 1.5; margin: 0 0 10px; }
.guide-lock-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr)); gap: 10px; }
.guide-lock-card {
  background: #fff; border: 1px solid var(--grey-200); border-top: 3px solid var(--eu-blue);
  border-radius: 12px; padding: 10px 14px;
}
.guide-lock-k {
  margin: 0 0 6px; font-size: 0.72rem; font-weight: 500; letter-spacing: 0.02em;
  text-transform: uppercase; color: var(--eu-blue-dark);
  font-family: var(--mono);
}
.guide-lock-card ul { margin: 0; padding-left: 18px; }
.guide-lock-card li { font-size: 0.85rem; color: var(--grey-800); line-height: 1.5; margin-bottom: 4px; }
.guide-lock-card li:last-child { margin-bottom: 0; }
.guide-lock-ok {
  font-size: 0.85rem; color: var(--grey-800); line-height: 1.5;
  background: var(--risk-minimal-bg); border-left: 3px solid var(--risk-minimal);
  border-radius: 0 10px 10px 0; padding: 10px 14px; margin: 10px 0 0;
}
.guide-lock .guide-note { margin-top: 10px; }

/* Business types: everything under the three cards (user, 2026-09-14: "a bit
   crowded"). One even gap between blocks, set here rather than by each block's own
   margin, and a wider one before the Article 27 paragraph, which starts a new point. */
.guide-types-notes { display: flex; flex-direction: column; gap: 14px; margin-top: 20px; }
.guide-types-notes > * { margin: 0; }
.guide-types-notes > .guide-types-fria { margin-top: 10px; }

/* Inline cross-reference between guide tabs. A button, not an anchor: it swaps
   the visible panel rather than navigating, so it needs no href and stays
   keyboard-reachable without one. */

/* ── Feature-record card (How it works → SW in Library) ──
   Mirrors the shape of a real catalogue record so the guide shows the thing
   itself rather than describing it. Label column is fixed so every row's
   value starts on the same line; it collapses to stacked rows on narrow
   screens, where a 150px gutter would leave the values unreadably thin. */
.rec-card {
  border: 1px solid var(--grey-200);
  border-radius: 14px;
  overflow: hidden;
  margin: 0 0 14px;
  background: var(--white);
}
.rec-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 12px 16px;
  background: var(--eu-blue-light);
  border-bottom: 1px solid var(--grey-200);
}
.rec-head strong { font-size: 1rem; color: var(--eu-blue-dark); font-family: var(--display); }
/* "Risk assigned  [High-risk]" — the badge alone read as decoration, so it is
   labelled. flex keeps label and badge on one line when the header wraps. */
.rec-assigned {
  display: inline-flex; align-items: center; gap: 6px; flex-shrink: 0;
  font-size: 0.72rem; font-weight: 500; letter-spacing: 0.02em;
  text-transform: uppercase; color: var(--grey-600);
  font-family: var(--mono);
}
.rec-row {
  display: grid; grid-template-columns: 150px 1fr; gap: 14px;
  padding: 10px 16px;
  border-top: 1px solid var(--grey-100);
}
.rec-row:first-of-type { border-top: none; }
.rec-label {
  font-size: 0.72rem; font-weight: 500; letter-spacing: 0.02em; text-transform: uppercase;
  color: var(--grey-600); padding-top: 2px;
  font-family: var(--mono);
}
.rec-val { font-size: 0.85rem; color: var(--grey-800); line-height: 1.5; }
.rec-val code { font-size: 0.8rem; color: var(--eu-blue); word-break: break-all; }
.rec-hint { display: block; font-size: 0.75rem; color: var(--grey-500); font-style: italic; margin-top: 3px; }
@media (max-width: 620px) {
  .rec-row { grid-template-columns: 1fr; gap: 2px; }
}

.guide-tag { font-size: 0.72rem; font-weight: 500; padding: 2px 8px; border-radius: 999px; margin-left: 6px; white-space: nowrap; font-family: var(--mono); }
.tg-you    { color: var(--risk-minimal); background: var(--risk-minimal-bg); border: 1px solid var(--risk-minimal-border); }
.tg-rare   { color: var(--grey-600); background: var(--grey-100); border: 1px solid var(--grey-400); }
.tg-banned { color: var(--risk-high); background: var(--risk-high-bg); border: 1px solid var(--risk-high-border); }
/* method, not risk — deliberately blue so it can't be read as a risk level */
.tg-method { color: var(--eu-blue); background: var(--eu-blue-light); border: 1px solid var(--eu-blue); display: inline-block; margin: 6px 0 0 0; }

/* ⛔ nowrap KEPT THE GUIDE WIDER THAN A SMALL PHONE (found 2026-09-18, phone check at
   320px). Most of these badges are two or three words, where nowrap is exactly right —
   but a few carry a phrase ("schools, colleges, training providers", 274px), and a line
   that can never break sets a floor under the whole page: the card could not be narrower
   than its widest badge, so the guide scrolled sideways. They wrap below 560px. */
@media (max-width: 560px) {
  .guide-tag { white-space: normal; }
}
/* ⚠ .guide-note-inline had the same override here and no longer needs one — its nowrap
   is gone altogether, because it was overflowing on a wide screen too. */

/* key terms */
/* ⛔ .guide-terms REMOVED 2026-09-12 with the guide's "Key terms" tab — the definition
   list it styled was the only markup that used it. */

/* ═══════════════════════════════════════════════
   HOW IT WORKS v2 — tabbed layout (main + right rail)
   ═══════════════════════════════════════════════ */
.guide2 { max-width: 1080px; }
.guide2-head { margin-bottom: 16px; }
.guide2-title { font-size: 1.6rem; font-weight: 700; color: var(--grey-900); margin: 0 0 6px; font-family: var(--display); letter-spacing: -0.02em; }
.guide2-sub { font-size: 0.9rem; color: var(--grey-600); line-height: 1.5; max-width: 720px; margin: 0; }
/* Sits under the standfirst as a provenance line, not as a second sentence of it.
   ⛔ MADE SMALLER AND PLAINER (user, 2026-09-08: "can you make this smaller, just a
   small note"). It was 0.8rem with the date in bold, which gave a housekeeping fact
   the emphasis of a finding. It is a footnote about the page, not part of it — so:
   no bold anywhere, one quiet grey, small. */
.guide2-checked { font-size: 0.72rem; color: var(--grey-500); margin: 6px 0 0; font-family: var(--mono); }

.guide2-tabs { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 18px; padding: 4px; background: var(--grey-100); border-radius: 14px; width: fit-content; max-width: 100%; }
.guide-tab {
  font: inherit; font-size: 0.85rem; font-weight: 600; cursor: pointer;
  color: var(--grey-700); background: none; border: none;
  padding: 8px 14px;
  border-radius: 10px;
  transition: background 0.15s, color 0.15s;
}
.guide-tab:hover { color: var(--eu-blue); }
.guide-tab.active { color: var(--eu-blue-dark); font-weight: 700; background: var(--white); box-shadow: 0 1px 3px rgba(11, 27, 63, 0.10); }

.guide2-layout { display: grid; grid-template-columns: 1fr 264px; gap: 20px; align-items: start; }
.guide2-main { background: #fff; border: 1px solid var(--grey-200); border-radius: 16px; box-shadow: 0 1px 2px rgba(11, 27, 63, 0.04); padding: 24px 26px; }

.guide-panel { display: none; }
.guide-panel.active { display: block; animation: guideFade .18s ease; }
@keyframes guideFade { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }

.guide-flow-img { width: 100%; max-width: 620px; height: auto; display: block; margin: 4px 0 18px; }

/* ── The four steps, as tiles (2026-09-17) ───────────────────────────────────
   Replaced a flat PNG. Same icons, colours and gradient tiles as the Home workflow row
   (.dash-flow-icon) and the landing page (.lp-icon), so the three places read as one.
   Four tiles with a chevron between; two by two on a narrow screen, where the chevrons
   would point at nothing. */
.gsteps {
  list-style: none; margin: 4px 0 20px; padding: 0;
  display: flex; align-items: stretch; gap: 4px;
}
.gsteps-step {
  --accent: #3b5bdb; --accent-2: #5c7cfa;
  flex: 1 1 0; min-width: 0;
  display: flex; flex-direction: column; align-items: center; text-align: center; gap: 8px;
  padding: 18px 10px 16px;
  background: var(--white); border: 1px solid var(--grey-200); border-radius: 14px;
}
/* nth-child 3/5/7, not nth-of-type 2/3/4: the chevrons are <li> too, so they count. */
.gsteps-step:nth-child(3) { --accent: #0ca678; --accent-2: #20c997; }
.gsteps-step:nth-child(5) { --accent: #e8590c; --accent-2: #fd7e14; }
.gsteps-step:nth-child(7) { --accent: #7048e8; --accent-2: #9775fa; }
.gsteps-icon {
  width: 52px; height: 52px; border-radius: 15px; margin-bottom: 2px;
  display: flex; align-items: center; justify-content: center; color: #fff;
  background: linear-gradient(140deg, var(--accent-2), var(--accent));
  box-shadow: 0 10px 22px -12px var(--accent), inset 0 1px 0 rgba(255, 255, 255, 0.35);
}
.gsteps-icon svg { width: 26px; height: 26px; }
.gsteps-n { font-family: var(--mono); font-size: 0.75rem; font-weight: 500; color: var(--accent); line-height: 1; }
.gsteps-t {
  font-family: var(--display); font-size: 0.9rem; font-weight: 700; line-height: 1.3;
  letter-spacing: -0.01em; color: var(--grey-900);
}
.gsteps-arrow { flex: none; display: flex; align-items: center; color: var(--grey-400); }
.gsteps-arrow svg { width: 18px; height: 18px; }
@media (max-width: 640px) {
  .gsteps { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .gsteps-arrow { display: none; }
}


/* risk-level cards */
.lvl-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr)); gap: 12px; margin-top: 8px; }
.lvl-card { border: 1px solid var(--grey-200); border-top: 4px solid var(--grey-400); border-radius: 14px; padding: 14px 16px; }
.lvl-card p { font-size: 0.85rem; color: var(--grey-600); line-height: 1.5; margin: 6px 0 0; }
.lvl-name { font-size: 1.05rem; font-weight: 700; font-family: var(--display); }
.lvl-ref { font-size: 0.72rem; font-weight: 500; color: var(--grey-600); text-transform: uppercase; letter-spacing: 0.02em; font-family: var(--mono); }
.lc-unacc { border-top-color: var(--risk-unacceptable); } .lc-unacc .lvl-name { color: var(--risk-unacceptable); }
.lc-high  { border-top-color: var(--risk-high); }         .lc-high  .lvl-name { color: var(--risk-high); }
.lc-lim   { border-top-color: var(--risk-limited); }      .lc-lim   .lvl-name { color: var(--risk-limited); }
.lc-min   { border-top-color: var(--risk-minimal); }      .lc-min   .lvl-name { color: var(--risk-minimal); }
.lc-high-t { color: var(--risk-high); } .lc-lim-t { color: var(--risk-limited); } .lc-min-t { color: var(--risk-minimal); } .lc-unacc-t { color: var(--risk-unacceptable); }

/* ── obligations by level (How it works → Your obligations) ──
   These two classes were in the markup with NO rule anywhere in either stylesheet,
   so the tab rendered as bare stacked divs: no columns, no card, no separation
   between one level's duties and the next. Modelled on .lvl-grid / .lvl-card, which
   is what the neighbouring tab uses for the same shape. Found 2026-08-26. */
/* ⛔ minmax(min(260px, 100%), 1fr), NOT minmax(260px, 1fr) (found 2026-09-18, phone check
   at 320px). A bare pixel floor is a floor even when the screen is narrower than it: the
   column stayed 260px wide, took its card's padding with it, and pushed the whole guide
   page sideways on a small phone. Wrapping it in min(…, 100%) lets the floor give way
   once the container is narrower, which is the only case it was ever wrong in.
   ⚠ The same shape is used by five other grids here (.lib-browse-grid, .guide-lock-grid,
   .lvl-grid, .area-grid, .type-cards) and all six were changed together. A new one copied
   from an old example will bring the bug back. */
.obligation-cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr)); gap: 12px; margin: 8px 0; align-items: start; }
.obligation-card { border: 1px solid var(--grey-200); border-radius: 14px; padding: 14px 16px; }
.obligation-card .guide-list { margin: 6px 0 0; }
.obligation-card .guide-list li { font-size: 0.85rem; color: var(--grey-800); }
.obligation-card .guide-list li em { color: var(--grey-600); font-size: 0.94em; }
/* The AI-literacy row sits ABOVE the level columns, as it does in the Actions
   Tracker. Tinted so it reads as a baseline that applies to everything below it. */
.ob-baseline { background: var(--eu-blue-light); border-color: var(--eu-blue); margin-bottom: 12px; }
.ob-baseline .lvl-name { color: var(--eu-blue-dark); }

/* A start date, not a risk level and not a method — deliberately neutral grey so it
   cannot be misread as either.
   ⚠ margin-left ONLY, never the `margin` shorthand. .guide-tag supplies the gap that
   separates the badge from the title beside it; a shorthand here silently cancels it
   and the card reads "High-riskfrom 2 Dec 2027". Exactly the trap documented on
   .type-card > strong above — walked into on 2026-08-26, reported by the user, fixed. */
.tg-date { color: var(--grey-600); background: var(--grey-100); border: 1px solid var(--grey-400); display: inline-block; margin-left: 8px; }
/* Room for the badge on the cards where it wraps onto its own line ("Transparency
   obligation" is already wide before its date is added). Same fix, same reason, as
   the line-height on .type-card > strong. */
.obligation-card .lvl-name { line-height: 1.8; }

/* annex areas grid */
.area-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(230px, 100%), 1fr)); gap: 10px; margin: 8px 0; }
.area-card { display: flex; gap: 10px; align-items: flex-start; border: 1px solid var(--grey-200); border-radius: 12px; padding: 10px 12px; }
.area-n { flex-shrink: 0; width: 24px; height: 24px; border-radius: 8px; background: var(--grey-100); color: var(--grey-600); font-weight: 500; font-size: 0.8rem; display: flex; align-items: center; justify-content: center; font-family: var(--mono); }
.area-body { display: flex; flex-direction: column; gap: 4px; }
.area-body strong { font-size: 0.85rem; color: var(--grey-800); line-height: 1.35; }
.area-body .guide-tag { align-self: flex-start; margin-left: 0; }


/* business type cards */
.type-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr)); gap: 12px; margin: 8px 0; }
.type-card { border: 1px solid var(--grey-200); border-radius: 14px; padding: 14px 16px; }
/* The badge beside the title is .tg-method, whose `margin: 6px 0 0 0` shorthand
   cancels the `margin-left` it would otherwise inherit from .guide-tag — so the
   gap has to come from the title. line-height gives the badge room to breathe on
   the cards where it wraps onto its own line (e.g. "Transparency obligation"). */
.type-card > strong { font-size: 1rem; color: var(--eu-blue-dark); margin-right: 8px; line-height: 1.8; font-family: var(--display); }
.type-card .guide-p { margin: 6px 0 0; }
/* SW in Library's three Manual-assessment answers (user, 2026-09-14): the badge goes
   UNDER every title. "No AI" is short enough to keep its badge beside it while the
   other two wrapped, so the row of three read unevenly. */
.type-cards-stack .type-card > strong { display: block; line-height: 1.5; }


/* right rail */
.guide2-rail { display: flex; flex-direction: column; gap: 14px; position: sticky; top: 16px; }
.rail-card { background: #fff; border: 1px solid var(--grey-200); border-radius: 16px; box-shadow: 0 1px 2px rgba(11, 27, 63, 0.04); padding: 16px; }
.rail-title { font-size: 0.75rem; font-weight: 500; text-transform: uppercase; letter-spacing: 0.02em; color: var(--grey-600); margin-bottom: 10px; font-family: var(--mono); }
.rail-lvl { display: flex; flex-direction: column; padding: 8px 0 8px 12px; border-left: 4px solid var(--grey-400); margin-bottom: 6px; }
.rail-lvl span { font-size: 0.85rem; font-weight: 700; color: var(--grey-800); }
.rail-lvl small { font-size: 0.72rem; color: var(--grey-600); }
.rail-lvl.lv-unacc { border-left-color: var(--risk-unacceptable); }
.rail-lvl.lv-high  { border-left-color: var(--risk-high); }
.rail-lvl.lv-lim   { border-left-color: var(--risk-limited); }
.rail-lvl.lv-min   { border-left-color: var(--risk-minimal); }
.rail-cta .guide-p { margin: 0 0 12px; }
.rail-cta .btn { width: 100%; text-align: center; }

@media (max-width: 880px) {
  .guide2-layout { grid-template-columns: 1fr; }
  .guide2-rail { position: static; flex-direction: row; flex-wrap: wrap; }
  .rail-card { flex: 1 1 240px; }
}

.guide-tree-img { display: block; width: 100%; max-width: 360px; height: auto; margin: 8px 0 4px; }

/* ═══════════════════════════════════════════════
   USE-FIRST ASSESSMENT (phase24)
   Step 1 = the uses. Step 2 = the switch checks. Step 3 = the contradiction.
   ═══════════════════════════════════════════════ */

.step-num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; border-radius: 50%;
  background: var(--eu-blue); color: #fff;
  font-size: 0.8rem; font-weight: 700; margin-right: 8px;
}

/* ── The step shell ───────────────────────────────
   Each step is its own card with a banner head. Without it the builder reads as
   one continuous document and the eye can't find where a step begins. */
.ra-step {
  background: var(--white);
  border: 1px solid var(--grey-200);
  border-radius: 16px;
  box-shadow: 0 1px 2px rgba(11, 27, 63, 0.04);
  overflow: hidden;
}
.ra-step-head {
  padding: 16px 22px;
  background: var(--eu-blue-pale);
  border-bottom: 1px solid var(--grey-200);
}
.ra-step-head .section-title { margin: 0; display: flex; align-items: center; }
.ra-step-head .section-desc { margin: 7px 0 0 32px; }
/* The step title carries the explanation in a ⓘ, so it needs to be legible next to
   an h2 rather than a field label. */
.section-title .info-ico { width: 17px; height: 17px; font-size: 0.72rem; flex: 0 0 auto; }
.ra-step-body { padding: 20px 22px; }

/* ── Step 1: the uses ─────────────────────────────
   One block per risk category, colour-coded with the SAME three tokens the tier
   dots use — no new palette, so a colour means the same thing everywhere. */
.use-block {
  margin-bottom: 20px;
  border: 1px solid var(--grey-200);
  border-left: 4px solid var(--grey-400);
  border-radius: 14px;
  overflow: hidden;
}
.use-block:last-child { margin-bottom: 0; }
.use-block-head {
  padding: 11px 14px;
  background: var(--grey-50);
  border-bottom: 1px solid var(--grey-200);
}
.use-block-body { padding: 12px 14px; }
/* Folding (toggleUseBlock, 2026-10-09): the head is the click target, status + Hide/Show on the right. */
.use-block-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; cursor: pointer; }
.use-block-headtext { flex: 1 1 260px; min-width: 0; }
.use-block-status { flex: none; }
.use-block-toggle { margin-left: 0; }
.use-block-closed .use-block-head { border-bottom: none; }
.use-block-closed .use-block-body { display: none; }
.use-block-title {
  font-family: var(--display); font-size: 1.05rem; font-weight: 700; margin: 0;
  color: var(--eu-blue-dark);
  letter-spacing: -0.02em;
}

.use-block-A { border-left-color: var(--risk-unacceptable); }
.use-block-A .use-block-head { background: var(--risk-unacceptable-bg); border-bottom-color: var(--risk-unacceptable-border); }
.use-block-A .use-block-title { color: var(--risk-unacceptable); }

.use-block-B { border-left-color: var(--risk-high); }
.use-block-B .use-block-head { background: var(--risk-high-bg); border-bottom-color: var(--risk-high-border); }
.use-block-B .use-block-title { color: var(--risk-high); }

.use-block-C { border-left-color: var(--risk-limited); }
.use-block-C .use-block-head { background: var(--risk-limited-bg); border-bottom-color: var(--risk-limited-border); }
.use-block-C .use-block-title { color: var(--risk-limited); }
.use-block-desc { font-size: 0.85rem; color: var(--grey-600); margin: 2px 0 0; }

.use-row {
  background: var(--white); border: 1px solid var(--grey-200);
  border-radius: 12px; padding: 10px 14px; margin-bottom: 6px;
  transition: border-color 0.15s;
}
.use-row:hover { border-color: var(--grey-400); }
/* The ⚠ caveat question (C2b — Art 50(4), the one Article 50 duty that falls on the
   deployer rather than the maker) keeps its ⚠ mark in the question text, but no
   special background: the row should read as one of the list, not as an alarm. */

/* Question left, answers right — the buttons line up into one rail down the page
   so 29 questions can be answered without the eye hunting for the controls. */
.use-main {
  display: grid; grid-template-columns: 1fr auto;
  gap: 16px; align-items: center;
}

/* Once answered, the row recedes — what's left undone stays visually loud. */
.use-row:has(.use-btn.selected) { background: var(--grey-100); }
.use-row:has(.use-btn.selected) .use-text { color: var(--grey-600); }

/* The Annex III area headings — how a customer navigates a long list: "is this us?" */
.use-area {
  font-family: var(--mono); font-size: 0.75rem; font-weight: 500; text-transform: uppercase; letter-spacing: 0.03em;
  color: var(--grey-600); margin: 18px 0 8px;
  padding-bottom: 4px; border-bottom: 1px solid var(--grey-200);
}
.use-block .use-area:first-child { margin-top: 0; }
/* ⚠ In the REPORT each area heading is wrapped with its first question (.rpt-area-keep, for
   printing), so the heading is now always a first child and the question a last child. These
   two lines keep the screen exactly as before: the gap above every heading but the block's
   first, and the rule under the wrapped question when more follows it. */
.use-block .rpt-area-keep:not(:first-child) > .use-area { margin-top: 18px; }
.rpt-area-keep:not(:last-child) > .rpt-q:not(.rpt-q-ns) { border-bottom: 1px solid var(--grey-200); }

.use-q { display: flex; gap: 10px; align-items: flex-start; }
/* A tier dot, not the internal question id. B10 / B5 meant nothing to anyone. */
.use-tierdot {
  flex: 0 0 auto; width: 10px; height: 10px; padding: 0; border-radius: 50%;
  margin-top: 5px; font-size: 0;
}
.use-text { font-size: 0.9rem; color: var(--grey-800); line-height: 1.5; }

.use-act { margin: 6px 0 0 22px; }
.use-act summary {
  font-size: 0.75rem; font-weight: 600; color: var(--eu-blue);
  cursor: pointer; list-style: none;
}
.use-act summary::-webkit-details-marker { display: none; }
.use-act summary::before { content: '▸ '; }
.use-act[open] summary::before { content: '▾ '; }
.use-ref { font-size: 0.75rem; color: var(--grey-600); margin-top: 4px; }
/* Whose duty the quoted provision is. Sits above the quote, not below it, so the
   reader knows who "Providers shall ensure…" is talking to before they read it. */
.use-owner {
  font-size: 0.8rem; line-height: 1.5; color: var(--eu-blue-dark);
  background: var(--eu-blue-light); border-left: 3px solid var(--eu-blue);
  padding: 6px 10px; border-radius: 0 8px 8px 0; margin: 0 0 6px;
}

/* Fixed width so every row's buttons sit on the same vertical line, whatever the
   length of the question next to them. */
/* An exemption written into the provision itself — "this shall not include…",
   "with the exception of…". Quiet by default, because it qualifies the question
   rather than asking a second one; it takes the row's colour once it IS the
   answer. Not a fourth pill in the rail: it needs a sentence to be safe to give,
   and a wide button among three narrow ones reads as another one-word answer. */
.use-exempt {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin: 8px 0 0 26px; padding: 7px 12px;
  background: var(--grey-100); border-left: 3px solid var(--grey-400);
  border-radius: 0 8px 8px 0;
}
.use-exempt.selected { background: var(--eu-blue-pale); border-left-color: var(--eu-blue); }
.use-exempt-text { flex: 1 1 240px; font-size: 0.8rem; color: var(--grey-700); line-height: 1.5; }
.use-exempt-text strong { color: var(--eu-blue-dark); }
.use-exempt-out { font-weight: 700; color: var(--eu-blue-dark); margin-top: 3px; }
.use-exempt-tick {
  display: flex; align-items: center; gap: 8px; flex: none; cursor: pointer;
  font-size: 0.8rem; font-weight: 700; color: var(--grey-800); white-space: nowrap;
}
.use-exempt-tick input { accent-color: var(--eu-blue); width: 15px; height: 15px; cursor: pointer; }
.use-exempt.selected .use-exempt-tick { color: var(--eu-blue-dark); }
/* Until the answer is Yes there is nothing to qualify, so the tick is inert — but
   the sentence stays readable, because it is what tells them whether Yes is the
   right answer in the first place. */
.use-exempt-idle .use-exempt-tick { color: var(--grey-500); font-weight: 600; cursor: default; }
.use-exempt-idle .use-exempt-tick input { cursor: default; }
.use-act-ex { font-size: 0.75rem; font-weight: 700; color: var(--eu-blue-dark); margin-top: 10px; }

.use-answers { display: flex; gap: 6px; flex: 0 0 auto; }
.use-btn {
  font: inherit; font-size: 0.8rem; font-weight: 600; cursor: pointer;
  padding: 5px 0; width: 62px; text-align: center; border-radius: 999px;
  border: 1px solid var(--grey-400); background: var(--white); color: var(--grey-800);
}
.use-btn.use-ns { width: 74px; }
.use-btn:hover { border-color: var(--eu-blue); color: var(--eu-blue); }
/* Neutral, for the same reason as the Step 2 buttons: "Yes, we screen job applicants
   with AI" is a truthful answer, not a wrong one. Red-for-yes would tell people the
   safe-looking answer is the desirable one — the last thing a compliance tool should
   do. The risk level is shown by the tier dot; the button only records the answer. */
.use-btn.selected {
  background: var(--eu-blue); border-color: var(--eu-blue); color: #fff;
}

/* ⛔ ON A PHONE THE QUESTION HAD ABOUT 95px (found 2026-09-18, first phone-width check).
   "Question left, answers right" is a grid of 1fr and an answer block that never
   shrinks: three fixed-width buttons, 198px together. At 390px that left one or two
   words per line for all 29 questions, and "Not sure" still fell off the right edge.
   Below 560px the answers go UNDER the question and share the width between them —
   which also makes them a proper size to tap, instead of 25px tall.
   ⚠ MUST STAY BELOW .use-btn.use-ns, and match its specificity: a plain .use-btn in
   here loses to that rule's extra class however far down the file it sits. */
@media (max-width: 560px) {
  .use-main { grid-template-columns: minmax(0, 1fr); gap: 10px; align-items: start; }
  .use-answers { width: 100%; gap: 8px; }
  .use-answers .use-btn,
  .use-answers .use-btn.use-ns { flex: 1 1 0; width: auto; padding: 10px 4px; }
  /* The "Not yet — from 2 December 2026" badge is 207px and never wraps, and it sat
     on the same flex line as the question, so on the eleven rows that carry one the
     question was crushed a second time — and the badge itself ran off the edge.
     A two-column grid gives the badge the line under the question, still at its own
     width (justify-self), lined up with the text rather than the tier dot. */
  .use-q { display: grid; grid-template-columns: 10px minmax(0, 1fr); column-gap: 10px; row-gap: 6px; }
  .use-applies { grid-column: 2; justify-self: start; margin-left: 0; }
}

.use-detail {
  margin: 10px 0 2px 22px; padding: 12px 14px;
  background: var(--eu-blue-light); border-radius: 12px;
}
.use-tools-label { font-size: 0.8rem; font-weight: 700; color: var(--eu-blue-dark); margin-bottom: 8px; }
.use-tools { display: flex; flex-direction: column; gap: 10px; }
.use-tool { display: flex; align-items: center; gap: 8px; font-size: 0.85rem; cursor: pointer; }
/* Under a ticked tool: which of its AI features does this, and is it on. Indented
   to the tick box it belongs to, so it reads as part of that answer rather than
   as a new question. */
.use-tool-wrap { display: block; }
.use-tool-feat {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
  margin: 5px 0 0 26px; padding: 6px 10px;
  background: var(--eu-blue-pale);
  border-left: 3px solid var(--eu-blue);
  border-radius: 0 8px 8px 0;
  font-size: 0.8rem;
}
.use-tool-feat-wait {
  background: var(--grey-100); border-left-color: var(--grey-300);
  color: var(--grey-600); font-style: italic;
}
.uft-name { font-weight: 700; color: var(--grey-900); }
/* The condition on a ⚠ feature, under the chip it qualifies. The chip is a wrapping
   flex row, so this claims a whole line of its own rather than squeezing in beside
   the pencil. A ⚠ row is nothing BUT its condition — the tool does not necessarily
   do this — so the mark can never appear here without it. */
.uft-cond {
  flex: 1 0 100%; margin-top: 2px;
  font-size: 0.75rem; line-height: 1.5; color: var(--grey-700);
}
.uft-tag {
  font-family: var(--mono); font-size: 0.72rem; font-weight: 500; text-transform: uppercase; letter-spacing: 0.02em;
  color: var(--grey-600); background: var(--white);
  border: 1px solid var(--grey-200); border-radius: 999px; padding: 1px 8px;
}
.uft-state { font-size: 0.72rem; font-weight: 700; border-radius: 999px; padding: 1px 9px; }
/* Neutral, exactly as the Step 2 switch buttons are: these record a FACT and do
   not grade it. Red-for-on read as "you have done something wrong" for a feature
   that is perfectly lawful to run; green-for-off read as "off is the right
   answer". Only "Not sure" is tinted, because it is the one that is still open. */
.uft-on      { color: #fff;                background: var(--eu-blue);         border: 1px solid var(--eu-blue); }
.uft-off     { color: var(--grey-700);     background: var(--grey-100);        border: 1px solid var(--grey-300); }
.uft-notsure { color: #8a5a00;             background: #fff8e6;                border: 1px solid #f0d9a0; }
.uft-icon {
  background: none; border: none; padding: 0 2px; cursor: pointer;
  font-size: 0.85rem; color: var(--eu-blue); opacity: 0.7;
}
.uft-icon:hover { opacity: 1; }
.uft-icon-del { color: var(--risk-high); }
.uft-icon-del:hover { color: #fff; background: var(--risk-high); border-radius: 5px; }
/* Nothing named yet. Not a warning — an unfinished answer, one click from done. */
.uft-name-btn {
  padding: 4px 12px;
  border: 1px dashed var(--eu-blue); border-radius: 20px;
  background: var(--white);
  font-size: 0.8rem; font-weight: 700; color: var(--eu-blue);
  cursor: pointer;
}
.uft-name-btn:hover { background: var(--eu-blue); color: #fff; border-style: solid; }

/* ── The naming dialog ────────────────────────────────────────────────────────
   Two questions, because the use and the tool are already known: which feature,
   and is it on. Everything the old four-field form asked — what it does, who
   oversees it, which uses it serves — is either already known here or an edit
   afterwards. */
.fm-box { max-width: 520px; }
.fm-box .dash-modal-actions {
  position: sticky;
  bottom: -22px;                 /* cancels the box's own bottom padding */
  margin-top: 18px;
  padding: 12px 0 22px;
  background: var(--white);
  border-top: 1px solid var(--grey-200);
}
/* The ✕ scrolls with the box, so the title it sits beside is never left behind. */
.fm-box .dash-modal-close { top: 10px; right: 10px; }
/* The level, then the use beneath it. Side by side, a long question was squeezed
   into what the pill left over and wrapped three or four times. */
.fm-use {
  display: flex; flex-direction: column; align-items: flex-start; gap: 6px;
  margin: 0 0 18px; padding: 10px 12px;
  background: var(--grey-50); border-radius: 12px;
  font-size: 0.85rem; line-height: 1.5; color: var(--grey-800);
}
.fm-use .risk-pill { flex: none; }
.fm-use-text { display: block; width: 100%; }
.fm-label {
  font-family: var(--mono); font-size: 0.72rem; font-weight: 500; text-transform: uppercase; letter-spacing: 0.02em;
  color: var(--eu-blue); margin: 0 0 7px;
}
.fm-opts { display: flex; flex-direction: column; gap: 2px; margin-bottom: 18px; }
.fm-opt {
  display: flex; align-items: baseline; gap: 9px;
  padding: 7px 9px; border-radius: 8px;
  font-size: 0.85rem; color: var(--grey-800); cursor: pointer;
}
/* The chosen feature's name is a labelled field like the three under it, so its
   label has to sit in the same column as theirs. That only holds if the radio is
   a FIXED width — browsers size it differently, and the note below is positioned
   by a fixed indent (9px padding + 14px radio + 9px gap = 32px). */
.fm-field-head { flex: 1 1 auto; min-width: 0; margin-top: 0; }
.fm-field-head .fm-field-val { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.fm-field-head .fm-opt-name { font-weight: 700; color: var(--grey-900); }
.fm-opt:hover { background: var(--grey-50); }
.fm-opt input[type="radio"] { width: 14px; height: 14px; margin: 0; flex: none; accent-color: var(--eu-blue); }
.fm-opt-name { flex: 0 1 auto; }
.fm-opt-tag {
  font-family: var(--mono); font-size: 0.72rem; font-weight: 500; text-transform: uppercase; letter-spacing: 0.02em;
  color: var(--grey-600); background: var(--grey-50);
  border: 1px solid var(--grey-200); border-radius: 999px; padding: 1px 8px; white-space: nowrap;
}
.fm-opt-other { align-items: center; }
.fm-info {
  flex: none; width: 18px; height: 18px; padding: 0; cursor: pointer;
  font: inherit; font-size: 0.72rem; font-weight: 700; line-height: 1;
  border-radius: 50%; border: 1px solid var(--eu-blue); background: var(--white); color: var(--eu-blue);
}
.fm-info:hover { background: var(--eu-blue); color: #fff; }
.fm-hint {
  margin: 2px 0 8px 42px; padding: 7px 10px; border-radius: 0 8px 8px 0;
  background: var(--eu-blue-pale); border-left: 3px solid var(--eu-blue);
  font-size: 0.75rem; line-height: 1.5; color: var(--grey-700);
}
.fm-hint.hidden { display: none; }
/* Same field the customer sees on a feature they already added, asked at the point
   it is being created. */
.fm-desc { margin: 4px 0 2px 42px; }
.fm-desc-label {
  display: block; font-size: 0.72rem; font-weight: 700;
  color: var(--eu-blue-dark); margin-bottom: 4px;
}
.fm-desc-opt { font-weight: 600; color: var(--grey-500); }
.fm-desc .fm-other-input { width: 100%; }
/* The customer's own features carry a bin; the option itself still fills the row,
   so the click target for choosing it does not shrink. */
.fm-row { display: flex; align-items: center; gap: 4px; }
.fm-row .fm-opt { flex: 1 1 auto; }
/* Deleting is the one destructive thing in this dialog, so it is the one control
   that is coloured. */
.fm-bin {
  flex: none; font: inherit; font-size: 0.95rem; line-height: 1; cursor: pointer;
  padding: 5px 8px; border-radius: 8px;
  background: var(--risk-high-bg); border: 1px solid var(--risk-high-border);
  color: var(--risk-high);
}
.fm-bin:hover { background: var(--risk-high); border-color: var(--risk-high); color: #fff; }
/* What it does and who oversees it — a name alone is not enough to recognise a
   feature months later. Indented under its option, not beside it. */
.fm-opt-note {
  font-size: 0.75rem; line-height: 1.5; color: var(--grey-600);
  /* 32px = the option row's own padding + radio + gap, so every label in this
     block starts on the same left edge as the AI FEATURE label above it. */
  margin: -2px 0 6px 32px; padding-right: 30px;
}
/* A level badge sitting in a field is a value, not a heading — it must not be
   pushed to full width by the flex row it lives in. */
.fm-opt-note .risk-pill { display: inline-block; }
/* What ⚠ means, said once, directly under the options that carry it — the moment
   the feature is chosen is the moment it has to be understood. */
.fm-other-input {
  flex: 1 1 140px; min-width: 0;
  padding: 6px 10px; font-size: 0.85rem;
  border: 1px solid var(--grey-300); border-radius: 10px;
}
.fm-other-input:focus { outline: none; border-color: var(--eu-blue); box-shadow: 0 0 0 3px rgba(0, 51, 153, 0.12); }
.fm-states { display: flex; flex-wrap: wrap; gap: 7px; }
.fm-err {
  margin-top: 12px; font-size: 0.8rem; font-weight: 700; color: var(--risk-high);
}
.fm-err.hidden { display: none; }
.use-tool-name { font-weight: 600; color: var(--grey-800); }
.use-tool-why { font-size: 0.75rem; color: var(--eu-blue); }
/* A conditional suggestion is not the same claim as "this tool has that feature",
   and it runs longer, so it wraps under the tick rather than trailing off the row. */
.use-tool-cond { display: block; margin: 2px 0 0 26px; line-height: 1.5; }
.use-tool-unknown { color: var(--grey-600); font-style: italic; }
.use-tools-empty { font-size: 0.85rem; color: var(--grey-600); font-style: italic; }

.use-note-label { display: block; font-size: 0.8rem; color: var(--grey-600); margin: 10px 0 4px; }
.use-note {
  width: 100%; font: inherit; font-size: 0.85rem; padding: 8px 10px;
  border: 1px solid var(--grey-300); border-radius: 10px;
  background: var(--white); resize: vertical;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.use-note:focus { outline: none; border-color: var(--eu-blue); box-shadow: 0 0 0 3px rgba(0, 51, 153, 0.12); }

/* ── Step 2: the switch checks ────────────────── */
/* .feature-row is a 3-column grid (22px checkbox | 1fr info | auto tier) built for
   the old tick list. A Step 2 row has no checkbox and only two children, so without
   this the description lands in the 22px column and wraps one word per line. */
/* ONE COLUMN now the switch has gone to the assessment (2026-09-03). The second column
   existed to hold three buttons; without it the description runs the full width and the
   row is as tall as its text rather than as tall as a stack of controls. The ✎/✕ on a
   customer-named feature still get a column of their own — hence auto, but only when
   .tc-controls is actually present. */
.tc-row {
  grid-template-columns: 1fr;
  align-items: start;
  background: var(--white);
  padding-top: 10px;
  padding-bottom: 10px;
}
.tc-row:has(.tc-controls) { grid-template-columns: 1fr auto; }
.tc-row .feature-info { min-width: 0; }        /* let long words wrap, not overflow */
.tc-row:hover { background: var(--grey-50); }

/* ⛔ The "answered rows recede" rule went with the buttons — it keyed off .fs-btn.selected,
   which is no longer on this card at all. Answered and unanswered are the same thing here
   now, because the library no longer holds that answer. */

.tc-controls { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; }

/* ── Already answered in Step 1 (2026-08-22) ───────────────────
   Step 1 records the use, the tool and the feature that does it, switch included.
   Step 2 still lists the feature — the complete picture is the point of the screen
   — but it states that answer instead of asking again, because two live controls
   over one stored value is how the Step 1 chip came to show a state that had been
   changed here.
   Deliberately NOT dimmed. It is the same answer as any other on the screen, given
   on the screen that owns it; a greyed row would read as an answer that counted for
   less. Three disabled buttons were the other option, and a disabled control is
   precisely what reads as broken. */
.tc-from { font-size: 0.8rem; color: var(--grey-700); margin-top: 6px; line-height: 1.5; }
.tc-from em { font-style: normal; font-weight: 600; color: var(--grey-800); }
.tc-controls-settled { gap: 7px; }
/* The same shape and colour as a chosen button, because that is what it is. */
.tc-given {
  display: inline-block; padding: 4px 10px; border-radius: 999px; white-space: nowrap;
  font-size: 0.75rem; font-weight: 600;
  background: var(--eu-blue); border: 1px solid var(--eu-blue); color: #fff;
}
/* Not a button: the answer is not given here. This goes to where it is given. */
.tc-jump {
  font: inherit; font-size: 0.75rem; font-weight: 600; cursor: pointer;
  background: none; border: 0; padding: 0; color: var(--eu-blue);
  text-decoration: underline; text-underline-offset: 2px;
}
.tc-jump:hover { color: var(--eu-blue-dark); }
.tc-jump:focus-visible { outline: 2px solid var(--eu-blue); outline-offset: 2px; }
/* What still needs checking sits above this line, what Step 1 settled below it.
   One column, same weight — the split is about what is left to do. */
.tc-divide {
  display: flex; align-items: center; gap: 10px;
  padding: 16px 16px 8px; font-family: var(--mono); font-size: 0.72rem; font-weight: 500;
  letter-spacing: 0.02em; text-transform: uppercase; color: var(--grey-600);
}
.tc-divide::after { content: ""; flex: 1 1 auto; height: 1px; background: var(--grey-200); }
/* The question the jump lands on, marked long enough to find it on a page of 31. */
.use-row-flash { animation: useRowFlash 1.8s ease-out; }
@keyframes useRowFlash {
  0%, 45% { background: var(--eu-blue-light); }
  100%    { background: transparent; }
}
@media (prefers-reduced-motion: reduce) {
  .use-row-flash { animation: none; background: var(--eu-blue-light); }
}
.fs-btn {
  font: inherit; font-size: 0.75rem; font-weight: 600; cursor: pointer;
  padding: 4px 10px; border-radius: 999px;
  border: 1px solid var(--grey-400); background: var(--white); color: var(--grey-800);
}
.fs-btn:hover { border-color: var(--eu-blue); color: var(--eu-blue); }
/* Neutral. These record a FACT, they do not grade it — green-for-off would imply
   switching it off is the "right" answer, and red-for-on that having it enabled is a
   failing. It is a High-risk feature either way; if it is on, "on" is the correct
   answer. The colour only says "this is what you told us". */
.fs-btn.selected {
  background: var(--eu-blue); border-color: var(--eu-blue); color: #fff;
}
/* The admin path is what makes "is this on?" answerable. There is deliberately no
   "on by default" badge — see phase25: a wrong path announces itself, a wrong
   default quietly reassures. */
/* "Anything not listed above?" (phase37). Set apart from the feature rows above
   it — it is a question about the LIST, not about a feature in it. */

/* ── Features the customer named themselves (phase38) ────────────
   Marked, not demoted. The catalogue misses features too — ten of Oracle HCM's
   uncatalogued agents were high-risk — so these rows get the same pills, the same
   three buttons and the same weight as any other. The tag and the tint say where
   the line came from, which is what the report's scope line says as well. */
.user-feature-row { background: var(--eu-blue-pale); }
.uf-tag {
  display: inline-block; margin-left: 8px; padding: 1px 7px; border-radius: 999px;
  font-size: 0.72rem; font-weight: 700; letter-spacing: 0.02em; vertical-align: middle;
  background: var(--eu-blue); color: #fff;
}
.uf-nonote { font-style: italic; color: var(--grey-600); }
.uf-basis { font-size: 0.8rem; color: var(--grey-800); margin-top: 6px; line-height: 1.5; }
.uf-edit { margin-top: 8px; display: flex; align-items: flex-end; gap: 10px; flex-wrap: wrap; }
/* The label sits ABOVE its drop-down, not beside it — as siblings in the flex
   row they lined up side by side and pushed Remove off the edge of the panel. */
.uf-edit > * { min-width: 0; }
.uf-label { display: block; font-size: 0.75rem; font-weight: 700; color: var(--eu-blue-dark); margin-bottom: 4px; }
/* The add form is four steps in a fixed order, and saying so out loud is the
   difference between a form and a list of boxes. The number is part of the
   label so it wraps with it and is read out with it. */
.uf-step {
  display: inline-flex; align-items: center; justify-content: center;
  width: 17px; height: 17px; margin-right: 7px; border-radius: 50%;
  background: var(--eu-blue); color: #fff;
  font-size: 0.66rem; font-weight: 700; line-height: 1; vertical-align: middle;
}
/* The way out when the whole premise is wrong: this tool has no AI at all. That
   is a Step 1 answer, so it is a sentence pointing there, not a fourth button
   here contradicting the screen above it. */
/* A drop-down is as wide as its longest option, so it must be told not to be.
   The option text is trimmed too — see useOptionText(). */
.uf-remove {
  font: inherit; font-size: 0.75rem; font-weight: 600; cursor: pointer;
  padding: 6px 12px; border-radius: 999px; background: #fff;
  border: 1px solid var(--grey-300); color: var(--grey-600);
}
.uf-remove:hover { border-color: #dc2626; color: #dc2626; }
/* Whose duty it is, at the size a list row can hold. The full sentence lives on
   the Step 1 row and in the report; repeating it on every option would bury the
   option itself. */

/* ⛔ .rpt-uf-* REMOVED 2026-09-12 with userFeatureUseTable(), the report table it
   styled. ⚠ Its comment here had gone stale and said the OPPOSITE of the code:
   "ticked and unticked, so the reader can see the alternatives that were considered",
   when the ticks-and-dashes version was deliberately dropped in September 2026. */


.uf-owner { font-size: 0.8rem; color: var(--grey-800); margin-top: 6px; }
.uf-owner-label { font-weight: 700; color: var(--eu-blue-dark); }
/* A blank oversight box is not an unassigned feature — it falls to the person
   named at the top of the assessment. The hint says so before they leave it
   blank; the fallback line says so afterwards, in a quieter weight so a real
   name against the feature still reads as the stronger record. */
.uf-owner-fallback .uf-owner-label { color: var(--grey-800); }
.uf-owner-why { color: var(--grey-600); font-weight: 400; }

/* The form. Sits under the "anything not listed?" question it answers. */
.uf-add { padding: 12px 0 2px; }
.uf-add-btn {
  font: inherit; font-size: 0.8rem; font-weight: 700; cursor: pointer;
  padding: 8px 16px; border-radius: 999px; background: #fff;
  border: 1px dashed var(--eu-blue); color: var(--eu-blue-dark);
}
.uf-add-btn:hover { background: var(--eu-blue-pale); }
.uf-add.hidden, .uf-add-btn.hidden, .uf-add-form.hidden { display: none; }
.uf-add-form {
  background: var(--grey-50); border: 1px solid var(--grey-200);
  border-radius: 14px; padding: 16px 18px; max-width: 520px;
}
.uf-add-title { font-family: var(--display); font-size: 1rem; font-weight: 700; color: var(--grey-900); margin-bottom: 10px; }
.uf-add-form .uf-label { margin-top: 10px; }
.uf-add-form .uf-label:first-of-type { margin-top: 0; }
.uf-input {
  width: 100%; box-sizing: border-box; font: inherit; font-size: 0.85rem; padding: 8px 10px;
  border: 1px solid var(--grey-300); border-radius: 10px; background: #fff;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.uf-input:focus { outline: none; border-color: var(--eu-blue); box-shadow: 0 0 0 3px rgba(0, 51, 153, 0.12); }
.uf-textarea { resize: vertical; }

.uf-add-err { margin-top: 10px; font-size: 0.8rem; font-weight: 600; color: #dc2626; }
.uf-add-err.hidden { display: none; }
.uf-add-actions { display: flex; gap: 10px; margin-top: 14px; }

/* What the check covered, in the report. Two lists, counted separately. */


.tc-where { font-size: 0.8rem; color: var(--grey-800); margin-top: 6px; }
.tc-where-label { font-weight: 700; color: var(--eu-blue-dark); }
.tc-nothing {
  font-size: 0.85rem; color: var(--grey-800); line-height: 1.5;
  background: var(--grey-100); border-radius: 12px; padding: 12px 14px;
}

/* ── Step 3: the reconciliation ──────────────── */
/* ⛔ THE FINDINGS PANEL'S STYLING IS GONE (removed 2026-09-12, code audit).
   .ra-findings, .findings-head/-ico/-title/-lead/-list and .finding, -line, -step,
   -what, -ans, -ans-on, -foot, -why — 14 rules for a panel whose markup was deleted
   with findingsReportSection() back in 2026-07-16. Nothing in any page or script
   has named one of those classes since; the CSS simply outlived the section. */

.ra-blockers { margin: 6px 0 0; padding-left: 20px; }
.ra-blockers li { margin-bottom: 3px; }

.rpt-art5 { border: 1px solid var(--risk-minimal-border); font-size: 0.9rem; color: var(--grey-800); line-height: 1.5;
  background: var(--risk-minimal-bg); border-left: 3px solid var(--risk-minimal);
  border-radius: 0 10px 10px 0; padding: 10px 14px; margin: 0 0 14px; }
.rpt-art5-bad { border-color: var(--risk-high-border); background: var(--risk-high-bg); border-left-color: var(--risk-high); }
/* Open items — a "Not sure" that was locked in. It carries no risk and no duties,
   so the report must not pretend the assessment is finished. Stated, never hidden. */
.rpt-art5-open { border-color: var(--risk-limited-border); background: var(--risk-limited-bg); border-left-color: var(--risk-limited); }
.rpt-art5-ex { border-color: var(--eu-blue); background: var(--eu-blue-pale); border-left-color: var(--eu-blue); }


/* ── The worked example: three small cards under the workflow ──
   Each takes its step's accent colour from the row above (--eg is set inline),
   so they read as belonging to steps 2, 3 and 4 rather than as a new section.
   About a third the height of a workflow tile, and no prose in them. */
/* Mirrors .dash-flow exactly — same display, same gap, same flex basis — so a
   card always sits under its own step. The empty slot is step 1 (no demo
   library) and the gaps stand in for the arrows. Matching the skeleton rather
   than guessing pixel widths is what keeps them aligned as the window resizes. */
.dash-eg-row {
  display: flex;
  align-items: stretch;
  gap: 4px;
  flex-wrap: nowrap;
  margin: -18px 0 26px;
}
.dash-eg-slot {
  flex: 1 1 0;
  min-width: 0;
  /* Nudges the three cards right. Applied to the EMPTY slot rather than as a
     transform on the row, so the cards stay inside the container instead of
     overhanging its right edge. One number to change if it needs more or less. */
  margin-right: var(--eg-nudge, 28px);
}
.dash-eg-gap  { flex: 0 0 22px; }        /* = .dash-flow-arrow svg width */
.dash-eg {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;   /* just the word and an arrow, centred like the tile above */
  gap: 8px;
  padding: 9px 14px;
  border: 1px solid color-mix(in srgb, var(--eg, var(--eu-blue)) 22%, transparent);
  border-radius: 999px;
  background: color-mix(in srgb, var(--eg, var(--eu-blue)) 7%, var(--white));
  text-decoration: none;
  color: inherit;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.dash-eg:hover {
  border-color: var(--eg, var(--eu-blue));
  background: color-mix(in srgb, var(--eg, var(--eu-blue)) 12%, var(--white));
}
/* The step's name is on the workflow tile directly above, so it is not repeated
   here — the card says "Example" and nothing else. */
.dash-eg-tag {
  flex: 0 0 auto;
  color: var(--eg, var(--eu-blue));
  font-family: var(--mono);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.02em;
}
.dash-eg-go {
  flex: 0 0 auto;
  color: var(--eg, var(--eu-blue));
  font-weight: 700;
  transition: transform 0.15s ease;
}
.dash-eg:hover .dash-eg-go { transform: translateX(3px); }

/* Which step the example belongs to. Hidden on a wide page, where the card sits
   under its own tile and the name is right above it. */
.dash-eg-of { display: none; color: var(--eg, var(--eu-blue)); font-family: var(--mono); font-size: 0.75rem; }

/* The workflow stacks into a column at 720px, so there is nothing left to line
   up with — drop the spacers and stack these too. */
@media (max-width: 720px) {
  .dash-eg-row { flex-direction: column; gap: 8px; margin-top: 8px; }
  .dash-eg-slot, .dash-eg-gap { display: none; }
  /* ⛔ ONCE STACKED, NOTHING SAYS WHICH STEP IS WHICH (found 2026-09-18, first
     phone-width check). The note above says the step's name "is on the tile directly
     above it" — true across a row, false in a column, where three identical
     "See example" pills sat in a line under all four tiles. So the name comes back,
     on the narrow layout only. */
  .dash-eg-of { display: inline; }
}

/* ── The pass card, on the dashboard home ──────────────────────
   Sits under the workflow, where the old plan card sat. A pricing card, not a
   text box: what you get is a scannable tick list and the price is a number.
   Two columns — what you get on the left, what it costs on the right — with the
   right-hand side tinted so the eye lands on the figure. */
.pass-card {
  display: grid;
  grid-template-columns: 1fr 292px;
  gap: 0;
  padding: 0;
  overflow: hidden;
  transition: box-shadow 0.35s ease, border-color 0.35s ease;
}
.pass-card-body { padding: 26px 28px; min-width: 0; }
.pass-card-buy {
  display: flex;
  flex-direction: column;
  gap: 12px;
  justify-content: center;
  padding: 26px 24px;
  background: linear-gradient(180deg, var(--grey-50) 0%, var(--grey-100) 100%);
  border-left: 1px solid var(--grey-200);
}

/* State chip */
.pass-chip {
  display: inline-block;
  margin-bottom: 14px;
  padding: 4px 11px;
  border-radius: 999px;
  font-family: var(--mono);
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.02em;
}
.pass-chip.live  { background: #e6f4ea; color: #17663a; }
.pass-chip.ended { background: #fff4e5; color: #8a5a00; }
.pass-chip.none  { background: var(--eu-blue); color: #fff; }

.pass-headline {
  margin: 0 0 16px;
  font-family: var(--display);
  letter-spacing: -0.01em;
  font-size: 1.15rem;
  line-height: 1.35;
  font-weight: 700;
}

/* What you get. The whole point of the card — scannable, one idea per line. */
.pass-list { list-style: none; margin: 0; padding: 0; }
.pass-list li {
  position: relative;
  padding: 7px 0 7px 30px;
  font-size: 0.95rem;
  line-height: 1.5;
}
.pass-list-tight li { padding-top: 5px; padding-bottom: 5px; font-size: 0.9rem; }
.pass-tick {
  position: absolute;
  left: 0;
  top: 7px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 19px;
  height: 19px;
  border-radius: 50%;
  background: #e6f4ea;
  color: #17663a;
  font-size: 0.72rem;
  font-weight: 700;
}
.pass-list-tight .pass-tick { top: 5px; }


/* Price block */
.pass-buy-price { margin: 0; text-align: center; line-height: 1.2; }
.pass-buy-amount {
  display: block;
  font-family: var(--display);
  font-size: 2.6rem;
  font-weight: 800;
  letter-spacing: -0.03em;
  color: var(--eu-blue);
}
.pass-buy-per {
  display: block;
  margin-top: 5px;
  font-size: 0.8rem;
  color: var(--grey-600);
}
.pass-buy-btn { width: 100%; font-size: 1rem; padding: 11px 18px; }
.pass-fine {
  margin: 0;
  font-size: 0.8rem;
  line-height: 1.5;
  color: var(--grey-600);
  text-align: center;
}

/* The three objections people have to a payment button, answered next to it. */
/* Said before the money, not after it. The pass is fully consumable inside a
   few days — a report can be downloaded the same afternoon — so the no-refund
   term has to be visible at the point of purchase, next to the free worked
   example that makes it fair. Smaller than the bullet list above it: a term to
   be read, not a selling point. */
.pass-refund-note {
  margin: 12px 0 0;
  font-size: 0.75rem;
  line-height: 1.65;
  color: var(--grey-600);
}
/* The terms live one click from the payment button, not only in the footer —
   buying is the other moment that binds, and it should say so where the money
   leaves. Quieter than the refund note: a pointer, not a term to weigh. */
.pass-terms {
  margin: 10px 0 0;
  font-size: 0.72rem;
  line-height: 1.5;
  color: var(--grey-500);
  text-align: center;
}
.pass-terms a { color: var(--eu-blue); text-decoration: underline; text-underline-offset: 2px; }
/* Directly under the Buy button on the offer card (user, 2026-09-10): smaller, and
   tucked up against the button it qualifies. Adjacent-sibling on purpose, so the
   "pass ended" card, where the line follows the small print, keeps its spacing. */
.pass-buy-btn + .pass-terms { margin-top: 4px; font-size: 0.72rem; }

.pass-reassure {
  list-style: none;
  margin: 2px 0 0;
  padding-top: 12px;
  border-top: 1px solid var(--grey-200);
}
.pass-reassure li {
  position: relative;
  padding-left: 15px;
  font-size: 0.8rem;
  line-height: 1.8;
  color: var(--grey-600);
}
.pass-reassure li::before {
  content: '·';
  position: absolute;
  left: 4px;
  font-weight: 700;
}

/* Live state: the number is the message. */
.pass-big { margin: 0 0 12px; line-height: 1; }
.pass-big-num {
  font-family: var(--display);
  font-size: 2.4rem;
  font-weight: 800;
  letter-spacing: -0.03em;
  color: var(--eu-blue);
}
.pass-big-unit { margin-left: 9px; font-size: 1rem; color: var(--grey-600); }
.pass-card-ended .pass-big-num { font-size: 1.5rem; color: #8a5a00; }

.pass-bar {
  height: 7px;
  border-radius: 999px;
  background: var(--grey-200);
  overflow: hidden;
}
.pass-bar-fill {
  height: 100%;
  border-radius: 999px;
  background: var(--eu-blue);
  transition: width 0.4s ease;
}
.pass-line { margin: 12px 0 0; font-size: 0.95rem; line-height: 1.5; }

/* Brief highlight when arrived at from the top-bar button. */
.pass-card-flash {
  border-color: var(--eu-blue);
  box-shadow: 0 0 0 4px rgba(0, 51, 153, 0.14);
}

/* Top-bar button. Short, quiet, and never on screen while a pass is live. */
.dash-buy-pass {
  margin-right: 4px;
  padding: 7px 14px;
  border: 1px solid var(--eu-blue);
  border-radius: 999px;
  background: var(--eu-blue);
  color: #fff;
  font: inherit;
  font-size: 0.8rem;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
}
.dash-buy-pass:hover { background: var(--eu-blue-dark, #002a80); }

@media (max-width: 900px) {
  .dash-buy-pass { font-size: 0.8rem; padding: 6px 11px; }
}
@media (max-width: 760px) {
  /* Stack: what you get, then what it costs. Never the other way round. */
  .pass-card { grid-template-columns: 1fr; }
  .pass-card-body { padding: 22px 20px; }
  .pass-card-buy {
    border-left: 0;
    border-top: 1px solid var(--grey-200);
    padding: 20px;
  }
  .dash-buy-pass { display: none; }
}

/* ── The pass ──────────────────────────────────────────────────
   Shown on every page once the pass has run out. Deliberately not red: nothing
   has gone wrong and nothing has been taken away, so an error colour would
   misrepresent the state. */
.pass-frozen-notice {
  margin: 0 0 18px;
  padding: 14px 16px;
  border: 1px solid var(--grey-300);
  border-left: 4px solid var(--eu-blue);
  border-radius: var(--radius-md, 8px);
  background: var(--grey-50, #f8f9fb);
  font-size: 0.9rem;
  line-height: 1.5;
}
.pass-frozen-notice .btn { margin-left: 10px; vertical-align: baseline; }

/* Sidebar badge counts down. It only turns amber in the last week — earlier
   than that it is information, not a warning. */
.dash-plan-badge.badge-expiring {
  background: #fff4e5;
  color: #8a5a00;
}

/* Receipts in My Account. */
.pass-history { margin-top: 16px; }
.pass-history .acc-sub {
  margin: 0 0 8px;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--grey-600);
  font-family: var(--mono);
}
.pass-row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 7px 0;
  border-top: 1px solid var(--grey-200);
  font-size: 0.9rem;
  color: var(--grey-700);
}


.pass-more-btn {
  margin-top: 6px;
  padding: 4px 0;
  background: none;
  border: none;
  font: inherit;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--eu-blue);
  cursor: pointer;
}
.pass-more-btn:hover { text-decoration: underline; }

/* Type-to-confirm (phase47). For acts that cannot be undone and are too costly for a
   single click: deleting a tool from the shared catalogue (type its name — it takes
   its features from every organisation at once), and deleting your own account
   (type DELETE — user, 2026-09-21). */
.dash-modal-phrase {
  display: block;
  margin: 16px 0 0;   /* room under the warning; the buttons keep their own 24px */
  font-size: 0.8rem;
  color: var(--grey-700);
}
.dash-modal-phrase span { display: block; margin-bottom: 5px; font-weight: 600; color: var(--grey-900); }
.dash-modal-phrase .input { width: 100%; box-sizing: border-box; }
.dash-modal-actions .btn:disabled { opacity: 0.45; cursor: not-allowed; }

/* ── Leave feedback window (2026-09-15) — openFeedback() in dashboard.js ── */
.fb-sub { font-size: 0.85rem; color: var(--grey-600); line-height: 1.5; margin: 0 0 16px; }
.fb-label { display: block; font-size: 0.8rem; font-weight: 600; color: var(--grey-900); margin: 0 0 6px; }
.fb-stars { display: flex; gap: 2px; margin: 0 0 16px; }
.fb-star {
  border: none; background: none; padding: 2px 3px; cursor: pointer;
  font-size: 1.6rem; line-height: 1; color: var(--grey-400);
}
/* Gold, not the amber of a warning: a star is not a problem state. */
.fb-star.on { color: #f5b301; }
.fb-star:focus-visible { outline: 2px solid var(--eu-blue); border-radius: 4px; }
.fb-text {
  display: block; width: 100%; box-sizing: border-box; min-height: 110px; resize: vertical;
  padding: 10px 12px; border: 1px solid var(--grey-300); border-radius: 12px;
  font-family: var(--font); font-size: 0.9rem; line-height: 1.5; color: var(--grey-800);
  transition: border-color 0.15s, box-shadow 0.15s;
}
.fb-text:focus { outline: none; border-color: var(--eu-blue); box-shadow: 0 0 0 3px rgba(0, 51, 153, 0.12); }
.fb-count { font-size: 0.72rem; color: var(--grey-500); text-align: right; margin-top: 4px; font-family: var(--mono); }
.fb-err { font-size: 0.8rem; color: #dc2626; margin: 10px 0 0; }
.fb-thanks { font-size: 0.9rem; color: var(--grey-800); line-height: 1.5; margin: 0; }

/* A lock blocker names a tool; this is the way to it. The switches it is asking
   for live on that tool's card now, so the message has to carry an address. */
.ra-blocker-go {
  margin-left: 8px;
  font: inherit;
  font-size: 0.8rem;
  font-weight: 700;
  cursor: pointer;
  padding: 2px 10px;
  border-radius: 999px;
  border: 1.5px solid rgba(0,51,153,0.35);
  background: var(--eu-blue-pale);
  color: var(--eu-blue);
  white-space: nowrap;
}
.ra-blocker-go:hover { background: var(--eu-blue-light); }


/* ── FINAL CHECK — the AI in your software ───────────────────────────────────
   A read-only mirror of the software library, shown before the record is made
   permanent. Deliberately quieter than the register it mirrors: nothing here is a
   control, so nothing here should look like one. */
.fc-tool {
  border: 1px solid var(--grey-200);
  border-radius: 14px;
  padding: 12px 14px;
  margin-bottom: 10px;
  background: var(--white);
}
/* Amber down the edge for a tool with something still unrecorded — the same colour
   its chip carries in the library, so the two screens agree at a glance. */
.fc-tool-missing { border-left: 3px solid var(--risk-limited); }
.fc-tool-head {
  display: flex; align-items: center; gap: 10px;
  padding-bottom: 8px; margin-bottom: 6px;
  border-bottom: 1px solid var(--grey-100);
}
.fc-tool-name { font-family: var(--display); font-size: 1rem; font-weight: 700; color: var(--grey-900); }
.fc-todo {
  font-family: var(--mono); font-size: 0.72rem; font-weight: 500; text-transform: uppercase; letter-spacing: 0.02em;
  padding: 2px 9px; border-radius: 999px;
  background: var(--risk-limited-bg); color: var(--risk-limited); white-space: nowrap;
}
/* ⛔ .fc-ok WAS DEFINED HERE TOO, at font-weight 800 (removed 2026-09-12, code audit).
   The rule further down sets the same colour at 700 with a size, and being later it won
   every time — so this one had no effect on anything and editing it did nothing. */
/* The one control on the panel, and it leads AWAY from it: a change belongs on the
   tool's card, where it is dated and lands in that tool's history. */
/* ── STEP 1: the switch rows, now answered here rather than mirrored ──────────
   The feature and its vendor link read downwards on the left; the only controls sit
   on the right. Same shape as the library card had, so the two screens do not teach
   two different layouts for the same question. */
/* The feature name, what it does, and where its switch is documented — the three
   things somebody needs before they can answer "is this on?".
   ⚠ COMPACT ON PURPOSE. Twelve features for one vendor is a long list, and a long list
   is one nobody reaches the bottom of. The description is CLAMPED TO TWO LINES (it is
   there to recognise the feature, not to study it — the vendor's page is one click away)
   and the switch link sits on the same line as its label rather than a line of its own. */
.fc-name { font-weight: 600; color: var(--eu-blue-dark); line-height: 1.35; font-size: 0.95rem; }
/* ── What the AI does, on the row where the on/off answer is given ───────────
   ⛔ TWO CAPS REMOVED (user, 2026-09-05). They compounded: a 68ch measure held the
   text narrow while .fc-cell (flex: 1 1 260px) stretched to fill the row — which
   is the gap the user saw between the wording and the buttons — and a 2-line
   clamp then cut whatever was left. Most descriptions ended in three dots on the
   ONE screen where the customer has to decide whether a feature is switched on.

   The facts-only rebuild is why the measure no longer fits: a description now
   carries the vendor's quotation, its plan/licence sentence and its source, so it
   is long BY DESIGN. Asana's Smart import runs to about six lines.

   ⚠ A reading measure is still worth having — 96ch keeps the line from running the
   full width of a wide monitor — but it is now wider than the buttons leave, so it
   binds only on a very wide screen.
   ⛔ NOTHING IS TRUNCATED. A description cut mid-quotation is worse than a tall
   row: the same rule useLabel() follows for a declared use in the tracker. */
.fc-what {
  margin: 1px 0 0;
  font-size: 0.8rem;
  line-height: 1.5;
  color: var(--grey-700);
}
.fc-where {
  margin-top: 2px;
  display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap;
  font-size: 0.72rem;
}
.fc-where-lbl { color: var(--grey-900); font-weight: 700; }
/* STACKED ROW (user, 2026-10-07): name, description, where-to-check and the default use the
   full width; the three buttons sit underneath. Side by side, the buttons' column squeezed
   the text into 3–4 lines; full width it mostly takes 1–2, so Step 1 gets shorter. */
.fc-cell { flex: 1 1 100%; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.fc-btns { flex: 1 1 100%; display: flex; gap: 8px; flex-wrap: wrap; margin-top: 4px; }
/* "More info" — the description lives in a window now (openFeatInfo). A text link in
   look, a button in fact (keyboard, no navigation). */
.fc-more {
  font: inherit; font-size: 0.75rem; font-weight: 600; color: var(--eu-blue);
  background: none; border: 0; padding: 0; cursor: pointer; align-self: flex-start;
  border-bottom: 1px solid currentColor;
}
.fc-more:hover { color: var(--eu-blue-dark); }
.fi-tool { font-size: 0.72rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; color: var(--grey-500); margin-bottom: 4px; }
.fi-box .fm-field { display: flex; flex-direction: column; gap: 2px; margin-top: 12px; }
.fi-box { max-width: 600px; }
.fi-box .fm-field-label { flex: none; }  /* 94px is a WIDTH in the row layout, a height in this column */
.fi-box .fm-field-val { font-size: 0.875rem; line-height: 1.55; color: var(--grey-800); }
/* "Missing an AI feature? Add it here" under a tool's rows (2026-10-08) + its window (openFeatAdd). */
/* A customer-named feature in Step 1 — theirs, not a checked catalogue fact (2026-10-08). */
.fc-own {
  display: inline-block; vertical-align: 2px; margin-left: 6px; padding: 1px 8px; border-radius: 999px;
  background: var(--eu-blue-light); color: var(--eu-blue); font-family: var(--mono);
  font-size: 0.65rem; font-weight: 500; letter-spacing: 0.04em; text-transform: uppercase; white-space: nowrap;
}
/* Its ✕ (raRemoveUserFeature, 2026-10-09) — same red as the library's .lp-ico-remove. */
.fc-own-remove {
  display: inline-flex; align-items: center; justify-content: center; vertical-align: 1px;
  width: 20px; height: 20px; margin-left: 4px; padding: 0; border-radius: 50%; cursor: pointer;
  border: 1px solid rgba(220,38,38,0.35); background: var(--risk-high-bg); color: #dc2626;
  font-size: 0.7rem; line-height: 1;
}
.fc-own-remove:hover { border-color: #dc2626; background: #dc2626; color: #fff; }
.fc-own-remove:focus-visible { outline: 2px solid var(--eu-blue); outline-offset: 2px; }
/* A box, not a footnote (user, 2026-10-08: "stand out more"). */
.fc-add {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap;
  margin: 10px 0 4px; padding: 12px 14px; border-radius: 10px;
  background: var(--eu-blue-light); border: 1px dashed var(--eu-blue);
  font-size: 0.875rem; font-weight: 600; color: var(--eu-blue-dark);
}
.fc-add-q { display: inline-flex; align-items: center; gap: 8px; }
.fc-add-icon {
  display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px;
  border-radius: 50%; background: var(--eu-blue); color: #fff; font-size: 1rem; font-weight: 700; line-height: 1;
}
.fc-add-btn {
  font: inherit; font-size: 0.85rem; font-weight: 700; color: #fff; background: var(--eu-blue);
  border: 0; border-radius: 999px; padding: 7px 16px; cursor: pointer;
}
.fc-add-btn:hover { background: var(--eu-blue-dark); }
.fa-box { max-width: 520px; }
.fa-box .uf-label { margin-top: 12px; }
.fa-lead { font-size: 0.85rem; color: var(--grey-600); line-height: 1.5; margin: 0 0 4px; }
.fc-src {
  font-size: 0.75rem;
  color: var(--eu-blue);
  text-decoration: none;
  border-bottom: 1px solid currentColor;
  align-self: flex-start;
}
.fc-src:hover { color: var(--eu-blue-dark); }
/* No link because the vendor documents no switch. Said, not left blank: an empty
   space is a gap, "check the vendor's site" is an instruction. */
/* T2's labels beside a switch/default link (2026-10-07): which part, when, which section. */
.fc-scope { font-size: 0.72rem; color: var(--grey-700); }
.fc-scope + .fc-scope::before { content: '· '; color: var(--grey-500); }
.fc-section { font-size: 0.72rem; color: var(--grey-600); }
.fc-src-none { font-size: 0.75rem; color: var(--grey-500); font-style: italic; border: 0; }

/* ── STEP 3: the full picture ─────────────────────────────────────────────────
   Five sections, and the colour carries the difference — a FINISHED answer must
   not read as a warning. Mismatch is the only one that is actually wrong, so it
   is the only one in the high-risk red, and it sits at the top of the page. */
/* "Status of AI features" (user, 2026-10-09): one framed panel holding the five groups, named
   like the report's section, set apart from the Article 25 box below. */
.stl-panel {
  border: 1px solid var(--eu-blue-light); border-top: 4px solid var(--eu-blue);
  border-radius: 16px; padding: 16px 16px 4px; background: var(--eu-blue-pale);
}
.stl-panel-head { margin: 0 0 14px; }
.stl-panel-title {
  margin: 0; font-family: var(--display); font-size: 1.2rem; font-weight: 700;
  color: var(--eu-blue-dark); letter-spacing: -0.02em;
}
.stl-panel-sub { margin: 3px 0 0; font-size: 0.85rem; color: var(--grey-600); }
.stl-group {
  border: 1px solid var(--grey-200);
  border-left: 3px solid var(--grey-400);
  border-radius: 14px;
  padding: 14px 16px;
  margin-bottom: 12px;
  background: #fff;
}
/* Two answers that cannot both be true — the only red on the page. */
.stl-mismatch { border-left-color: var(--risk-high); background: var(--risk-high-bg); }
.stl-mismatch .stl-head h3 { color: var(--risk-high); }
/* Named in Step 2: settled, and where the work comes from. */
.stl-instep2 { border-left-color: var(--eu-blue); }
/* Running with nothing declared — the section that asks a question. */
.stl-unused { border-left-color: var(--risk-limited); }
/* Switched off is FINISHED, not outstanding. Green, like the tracker's done. */
.stl-off    { border-left-color: var(--risk-minimal); }
.stl-notsure{ border-left-color: var(--risk-unsure); }
.stl-head { display: flex; align-items: baseline; gap: 10px; }
.stl-head h3 { margin: 0; font-family: var(--display); font-size: 1.05rem; color: var(--eu-blue-dark); }
.stl-count {
  font-family: var(--mono); font-size: 0.75rem; font-weight: 500; color: var(--grey-700);
  background: var(--grey-100); border-radius: 999px; padding: 1px 9px;
}
.stl-lead { margin: 6px 0 10px; font-size: 0.85rem; color: var(--grey-700); }
.stl-list { list-style: none; margin: 0; padding: 0; }
.stl-row {
  display: flex; align-items: center; gap: 10px;
  padding: 5px 0; font-size: 0.85rem; border-top: 1px solid var(--grey-200);
}
/* ⚠ NO WRAPPING on these rows: tool, feature and box are one line, and the feature is
   what gives when the room runs out. */
.stl-row .stl-feat { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.stl-row:first-child { border-top: 0; }
.stl-tool { font-weight: 700; color: var(--eu-blue-dark); flex: none; }
.stl-feat { flex: 1 1 220px; min-width: 0; color: var(--grey-800); }
/* ⛔ .stl-src is gone with the vendor links (user, 2026-09-04) — every one of these
   features carries that link on its own row in Step 1, inches up the same page. */

/* What the row says about itself where the section is not already the answer. */
.stl-state {
  flex: none; font-size: 0.75rem; font-weight: 700; color: var(--grey-600);
  background: var(--grey-100); border-radius: 999px; padding: 1px 9px;
}
/* THE TICK, at the end of its own row (user, 2026-09-04). It used to take a full line of
   its own and repeat the claim on every row; the section's lead states it once, and the
   box carries it in a title and an aria-label for anyone who needs it said again. */
.stl-tick {
  flex: none; display: inline-flex; align-items: center; margin-left: auto; cursor: pointer;
}
.stl-tick input { width: 16px; height: 16px; accent-color: var(--eu-blue); cursor: pointer; }
/* Until it is ticked this row is the thing standing between them and a lock. */
.stl-row-todo { background: var(--risk-limited-bg); border-radius: 8px; padding-left: 8px; }
/* Over the COLUMN it acts on: the boxes sit at the right-hand end of each row, so a
   control for all of them belongs above that end, not at the left margin. */
.stl-bulk { display: flex; justify-content: flex-end; margin: 0 0 6px; }
.stl-all {
  font: inherit; font-size: 0.75rem; font-weight: 600; cursor: pointer;
  color: var(--eu-blue); background: var(--white);
  border: 1px solid var(--eu-blue-light); border-radius: 999px; padding: 4px 11px;
}
.stl-all:hover { border-color: var(--eu-blue); background: var(--eu-blue-pale); }

.fc-row {
  display: flex; align-items: flex-start; gap: 6px; flex-wrap: wrap;
  padding: 10px 0; font-size: 0.85rem; line-height: 1.5; color: var(--grey-800);
  border-top: 1px solid var(--grey-200);
}
.fc-row:first-of-type { border-top: 0; }
.fc-row-none .fc-name { color: var(--grey-600); font-style: italic; }
/* A tool with nothing to record because a question is still open (2026-10-04). */
.fc-row-warn { display: flex; flex-direction: column; align-items: flex-start; gap: 10px;
  background: var(--risk-limited-bg); border-left: 3px solid var(--risk-limited-border); }
.fc-warn-t { font-size: 0.85rem; color: var(--grey-800); line-height: 1.5; margin: 0; }
.fc-warn-t strong { display: block; color: var(--grey-900); margin-bottom: 2px; }


/* ── The map at the front of the report (2026-08-24) ─────────────────────────
   A stranger used to land in a list of tool names with no idea what they were
   about to read. One row per section, in the order they appear. */
.rpt-map {
  /* ⚠ ONE RULE, NOT TWO. This file has had .at-literacy-info and .at-literacy-tag
     defined twice from exactly this — properties added in a second block near the
     thing they affect instead of here. The grid below belongs to the same box. */
  display: grid; grid-template-columns: auto max-content minmax(0, 1fr);
  column-gap: 10px; row-gap: 6px; align-items: baseline;
  margin: 0 0 26px;
  padding: 16px 20px;
  border: 1px solid var(--eu-blue-light);
  border-left: 4px solid var(--eu-blue);
  border-radius: 14px;
  background: var(--eu-blue-pale);
  page-break-inside: avoid;
}
.rpt-map-title {
  font-size: 0.8rem; font-weight: 500; text-transform: uppercase; letter-spacing: 0.02em;
  color: var(--eu-blue); margin-bottom: 8px;
  font-family: var(--mono);
}
/* ⭐ THE NAME COLUMN SIZES ITSELF TO THE LONGEST TITLE (user, 2026-09-07: "stretch
   content so the name of sections are not in 2 lines"). It was a fixed 190px, which
   fitted the titles it was written for and wrapped "AI features switched on/off
   status" and "What your business uses AI for" onto two lines each.
   ⚠ A WIDER FIXED WIDTH WOULD ONLY MOVE THE PROBLEM to the next title somebody
   writes. max-content measures the real thing, so the column is exactly as wide as it
   needs to be and no wider — and because the GRID owns the column rather than each
   row owning its own width, every row still lines up.
   ⚠ display: contents on the row is what puts the three cells into the parent grid;
   it also drops the row's own padding, so the spacing moves to row-gap. */

.rpt-map-title { grid-column: 1 / -1; }
.rpt-map-row { display: contents; font-size: 0.8rem; line-height: 1.5; }
.rpt-map-n {
  width: 22px; height: 22px; display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%; background: var(--eu-blue); color: #fff; font-size: 0.72rem; font-weight: 700;
}
.rpt-map-name { white-space: nowrap; font-weight: 700; color: var(--grey-900); font-size: 0.8rem; }
.rpt-map-what { min-width: 0; color: var(--grey-700); font-size: 0.8rem; line-height: 1.5; }

/* The section names are set never to wrap, which on a phone left the description
   beside them about 67px — one word a line (found 2026-09-18, first phone-width
   check). Two columns instead of three: the number, then the name with its
   description on the line under it. Screen only; print is laid out at paper width. */
@media (max-width: 560px) {
  .rpt-map { grid-template-columns: auto minmax(0, 1fr); row-gap: 3px; }
  .rpt-map-name { white-space: normal; }
  .rpt-map-what { grid-column: 2; margin-bottom: 9px; }
}

/* ── §1 Your software: an inventory, no levels ───────────────────────────────
   Deliberately a plain table. Chips with coloured pills were what made this
   section state its conclusions before the evidence. */
/* ⛔ .rpt-sw-name and .rpt-sw-count removed 2026-09-12 (code audit) — a second, duplicate
   copy of rules that were also in style.css, for a per-tool report section that no longer
   exists. Neither class is written by anything. .rpt-sw-tag below IS live. */
.rpt-sw-tag {
  font-size: 0.68rem; font-weight: 500; padding: 1px 8px; border-radius: 999px;
  background: var(--eu-blue-light); color: var(--eu-blue); white-space: nowrap;
  font-family: var(--mono);
}
.rpt-sw-tag-manual { background: var(--grey-100); color: var(--grey-600); }

/* Labels on the Step 1 answer badges — "Yes / High" said neither what the answer
   was nor what the level referred to. */
.rpt-ans-k {
  font-size: 0.66rem; font-weight: 500; text-transform: uppercase; letter-spacing: 0.02em;
  color: var(--grey-500); margin-right: 6px;
  font-family: var(--mono);
}
/* ⚠ THE QUESTION'S LABEL SITS ON ITS OWN LINE, unlike the answer labels, which are
   inline before a badge. The question runs to several lines; a label tucked into the
   start of the first one would be read as the opening words of the sentence. */
.rpt-q-k { display: block; margin: 0 0 3px; }

/* Column headings on the duty tables: the middle column is when a duty STARTS to
   bind, which without a heading reads as the day the work was finished. */
.rpt-at-duties thead th {
  vertical-align: top;
  text-align: left;
  padding: 6px 12px 8px;
  border-bottom: 1.5px solid var(--grey-300);
  font-size: 0.62rem; font-weight: 500; text-transform: uppercase; letter-spacing: 0.02em;
  color: var(--grey-500);
  font-family: var(--mono);
}
.rpt-at-duties thead th:nth-child(2), .rpt-at-duties thead th:nth-child(3) { white-space: nowrap; }


/* ── The tracker card, after 2026-08-24 ──────────────────────────────────────
   The date column had no heading, so ten bare dates read as ten deadlines. It is
   when each duty STARTS to bind. One heading per card rather than a label repeated
   on every row — and it carries the odd values too ("Already applies"). */

/* The note is always on the card now — a button that revealed a box meant a note
   nobody had written was a note nobody knew they could write. Compact, because a
   tool has one note and a tracker can have eight. */
.at-note-compact { min-height: 2.6em; }


/* ── The tracker, explained on first arrival (2026-08-24) ────────────────────
   Somebody lands here straight from locking their first assessment. The page
   opened with a card called "AI literacy" and a row of tabs named after parts of
   the Act, none of which said what they were. Dismissable, and it stays dismissed
   — scaffolding for the first visit, not a permanent banner. */
/* The obligation list could not be read and the built-in copy is standing in.
   Amber, not red: nothing is wrong with the customer's record — the list on screen
   is simply not the whole one. Sits above the intro and cannot be dismissed. */
.at-fallback {
  margin: 0 0 18px;
  padding: 14px 18px;
  border: 1px solid var(--risk-limited-border);
  border-left: 4px solid var(--risk-limited);
  border-radius: var(--radius);
  background: var(--risk-limited-bg);
}
.at-fallback-title {
  font-size: 0.9rem; font-weight: 700; color: var(--grey-900); margin-bottom: 6px;
}
.at-fallback p {
  margin: 0; font-size: 0.85rem; line-height: 1.5; color: var(--grey-800);
}

.at-intro {
  position: relative;
  margin: 0 0 18px;
  padding: 16px 20px 14px 20px;
  border: 1px solid var(--eu-blue-light);
  border-radius: 14px;
  background: var(--eu-blue-pale);
}
/* ⛔ .at-intro-x IS GONE (user, 2026-09-06) — the ✕ that hid this note for ever.
   The note is the only route on this screen to the page explaining the
   obligations, so it is not the kind of thing a reader should be able to close. */
/* ⛔ .at-intro-title / -row / -name / -what / -foot ARE GONE (2026-09-05) with the
   explainer they styled — a second copy of the guide, kept in step by hand. What
   is left is one line pointing at the guide itself. */
.at-intro-slim { padding: 12px 20px 12px 20px; }
.at-intro-lead { margin: 0; font-size: 0.85rem; line-height: 1.5; color: var(--grey-800); }

/* ── The card's shared date, said once ───────────────────────────────────────
   Nine rows saying the same date hid the two that said something else.
   ⛔ .at-intro-when IS GONE (user, 2026-09-10) — the line left the intro box for
   the card itself (.at-card-when), where it shows on every card. On a high-risk
   card a second line under it carries Article 111(2). */
/* ⭐ AN "APPLIES FROM" ROW under the names (user, 2026-09-10): the date first, the
   rest behind "See more". ⛔ No "i" disc (not clickable, and every other disc here
   is) and no framed notes box — both tried and rejected the same day. */
.at-card-when-v { display: block; min-width: 0; font-size: 0.8rem; line-height: 1.5; color: var(--grey-700); }
/* ⭐ PLAIN TEXT, NOT A BUTTON (user, 2026-09-10: "not button, just 'see more' text").
   Still a <button> underneath so a keyboard and a screen reader can open it — only
   the look is text: same size and weight as the sentence, no underline until hover. */
.at-see-more {
  border: none; background: none; padding: 0; margin-left: 2px; cursor: pointer;
  font: inherit; color: var(--eu-blue);
}
.at-see-more:hover, .at-see-more:focus-visible { text-decoration: underline; }
.at-card-more { display: none; max-width: 96ch; }
.at-card-dates.open .at-card-more { display: block; }
.at-card-more-p { display: block; margin-top: 4px; font-size: 0.75rem; line-height: 1.5; }


/* ⛔ .at-ob-inline / .at-help-body ARE GONE (2026-09-06). They styled the block
   that opened under an obligation to show our explanation of it. The explanation
   is the Act's own words now, and it opens in the side panel. */


/* The tracker card labels what it names — the same two words the library card and
   the Step 1 dialog use for the same two facts. */


/* ── One card per tier (2026-08-24) ──────────────────────────────────────────
   The twelve Article 26 obligations are the same twelve for every high-risk
   feature, so a card per feature asked for the same ticks over and over. */
/* What a tick then means. It has to sit with the list it refers to, not below the
   obligations, or a tick is made before the sentence is reached. */

/* One obligation: the tick, what it is, when it binds, how to understand it, and
   the customer's own note on how it is met. */
.at-ob:last-child { border-bottom: none; }
.at-ob-done .at-duty-label { color: var(--grey-600); }
/* ⛔ .at-what IS GONE (2026-09-06) — the Expand / Collapse button on each
   obligation. Its own comment argued a word beats a glyph, and that was right for
   a control that revealed prose. The mark that replaced it is not a substitute for
   a word: .at-ob-info opens the Act text, the same ⓘ the literacy row has always
   had, and the two blocks on this screen finally have one shape. */
/* ⛔ .at-ob-note's FIRST HALF WAS HERE, and it was fighting the rule further down
   (merged 2026-09-12, code audit). This one set `margin: 8px 0 0 6px`, the later one
   `margin-top: 10px` — so only the TOP was overridden and the element rendered as a
   hybrid: 10px above from the new layout, 6px of left indent surviving from the old
   one, which neither comment described. Both now sit in the single rule below, at the
   values the screen was already showing.
   ⛔ `.at-ob-note .at-note-label` went with it: the note box has carried no visible
   heading since the label became an aria-label on the field, and test-at-layout.js:291
   asserts that markup is absent. */

/* The report card names the tier and lists what its obligations cover, matching
   the tracker screen. */
/* The customer's own words on how ONE obligation is met, under it. */
.rpt-at-obnote { margin-top: 5px; font-size: 0.8rem; line-height: 1.5; color: var(--grey-700); font-style: italic; }


/* ── What a tier's obligations cover: a block each ───────────────────────────
   ⚠ A tool name and a whole declared use were stacked as bare lines, so four tools
   read as one paragraph (user: "all squeezed under high risk"). */
/* A tick that says "on the list", not "done" — it is the covering list, and nothing
   here is a task. Grey rather than green, so it cannot be read as a completion. */

/* ── The obligations, under their own heading ─────────────────────────────────*/
/* ⚠ The tick boxes sat flush against the card's coloured tier edge (user: "all
   tickboxes are now touching red line"). The whole row is indented off it. */
/* ⚠ align-items: center, not baseline. Baseline was right when the row was text
   and a checkbox; the answer is now a pair of pill buttons, and baseline hangs them
   off the text's baseline instead of centring them on the line. */
/* ⚠ A GRID, NOT A FLEX ROW (user, 2026-09-05: "align expand buttons vertically so
   they are under each other"). As a wrapping flex row every column floated: the
   obligation names differ in length and only two rows in ten carry a date, so the
   control at the end landed in a different place on every line and the eye had to
   hunt for it. Columns put the answers in the same place on all of them.
   ⚠ IT STILL MATTERS WITH EXPAND GONE (2026-09-06): what has to line up now is the
   Done / Started / Not started trio, and that is the harder of the two — an
   answer that moves row to row is worse than an explanation that does.
   The date column is always PRESENT even when it prints nothing — see dateCell in
   renderAtGrid(), which emits an empty span rather than nothing at all. */
.at-ob-line {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 8px; align-items: center; padding-left: 6px;
}
/* ⚠ ONE LINE PER OBLIGATION (user, 2026-09-05: "there is enough space for one
   line only, it would look better as well"). The fixed columns were taking room
   the name needed — a 130px date column standing empty on eight rows in ten, and
   answer buttons padded for a wider screen. The date column sizes to its content
   now, so an empty one costs nothing while still holding the answers in line.
   ⛔ THE NAME IS NEVER TRUNCATED to make it fit. On a narrow window a long duty
   plus its badge still wraps — an obligation cut mid-word is worse than a tall
   row, which is the rule useLabel() already follows for a declared use. */
.at-ob-line .at-duty-label { white-space: normal; }
.at-ob-line .at-ext-badge { white-space: nowrap; }
/* Below the two-column layout the row has no room for four columns; it stacks the
   answers under the name rather than squeezing them. */
@media (max-width: 900px) {
  .at-ob-line { grid-template-columns: minmax(0, 1fr); }
  .at-ob-line .at-state { grid-column: 1 / -1; }
}
.at-ob { padding: 10px 0; border-bottom: 1px solid var(--grey-100); padding-left: 4px; }
/* ⚠ padding-RIGHT as well as left (user, 2026-08-28): the card had an 18px gutter
   on the tier edge and none on the other side, so the note box and the answer
   buttons — both of which reach the full width of the row — sat flush against the
   card's border. */
.at-card { margin: 0 0 12px; background: var(--white); border: 1px solid var(--grey-200); border-left: 4px solid var(--risk-high); border-radius: 16px; overflow: hidden; padding-left: 18px; padding-right: 18px; }
/* The separate "✓ Done" chip went with the checkbox on 2026-08-28: the answer is
   now a named button that fills in when chosen, so a chip beside it said the same
   thing twice. */


/* ⛔ .at-covers / .at-cover-* ARE GONE (2026-09-05) — the tier card that listed
   every feature one set of answers was claimed for. A panel is one feature now,
   named in its own heading, so there is nothing to enumerate. */

/* The tracker's status bar, under its name — where the library puts its own, and
   crucially NOT under the oversight field, whose helper line then read as a caption
   for the bar (user, 2026-08-24). */
.ra-meta-card .lib-count-bar { margin: 14px 0 16px; }

/* The badge explains itself on its own row (2026-08-24). It used to be a footnote
   at the foot of the page with nothing joining it to the badge it was about. */
/* ⚠ ALIGNED WITH THE DUTY IT IS ABOUT (user, 2026-09-06), not indented off it.
   The 36px was inherited from a layout that had a checkbox column in front of the
   name; that column went in August and the indent stayed, so the sentence hung
   30px right of the title it explains and read as belonging to nothing. 6px is
   what .at-ob-line and the note box both use. */
.at-ob-ext-line {
  margin: 6px 0 0 6px;
  padding: 7px 11px;
  border-radius: 10px;
  background: var(--risk-limited-bg);
  font-size: 0.8rem; line-height: 1.5; color: var(--grey-800);
}


/* The tracker list uses the same bar the tracker itself does, so opening a record
   does not change the shape of its own progress. */
.ra-card .lib-count-bar { margin: 8px 0 0; }
.ra-card .lib-prog { max-width: 220px; }

/* The Delete button centres on the whole main block; with the taller bar in it the
   block grew, so this pins the button rather than letting it ride the last line. */
.ra-card-actions { display: flex; gap: 8px; flex-shrink: 0; align-self: center; }


/* ⛔ .rpt-at-covers / .rpt-at-cover-* ARE GONE (2026-09-05), with the tracker's
   equivalent — a report card is one AI feature, named in .rpt-at-card-sw and
   .rpt-at-card-feat above. */

/* The date this level's obligations share, said once. On paper the repetition was
   worse than on screen: nine identical dates down a column. */
.rpt-at-when {
  margin: 0 0 10px;
  padding: 7px 11px;
  border-radius: 10px;
  background: var(--grey-50);
  font-size: 0.8rem; line-height: 1.5; color: var(--grey-700);
}
.rpt-at-obs-k {
  caption-side: top;
  text-align: left;
  padding: 16px 12px 12px;
  font-size: 1rem; font-weight: 700; color: var(--grey-900);
  text-transform: none; letter-spacing: -0.01em;
  font-family: var(--display);
}

/* ── The two answers an obligation can have (2026-08-28) ──────────────────────
   A tick box offers done or nothing, and compliance work has a third state:
   started, not finished. With nowhere to record it people ticked Done and
   explained themselves in the note, which is how a report came back claiming 100%
   complete above notes saying the work had not started.

   ⚠ EQUAL AND NAMED, at the user's insistence after a first cut that made
   Incomplete a small tick at the end of the line ("the small box is easy to miss,
   the big one doesn't say complete"). Both are legitimate answers; neither is the
   default. Same round-tick shape as .ais-opt on the library screen — one way of
   asking a question with a small set of answers — but each option carries its own
   colour, because unlike that control the two answers here are not equivalent:
   green is met, amber is not. */
.at-state { flex: none; display: inline-flex; gap: 5px; margin-left: auto; }
/* Trimmed 2026-09-05 so the obligation's name keeps its own line: three pills at
   the old padding took about 40px more than they needed, and the name paid. */
.at-state-opt {
  display: inline-flex; align-items: center; gap: 6px;
  font: inherit; font-size: 0.72rem; font-weight: 600; color: var(--grey-700);
  padding: 4px 10px 4px 8px; border-radius: 999px;
  border: 1px solid var(--grey-300); background: var(--white);
  cursor: pointer; white-space: nowrap;
  transition: border-color .12s, background .12s, color .12s;
}
.at-state-dot {
  position: relative; flex: 0 0 auto; width: 13px; height: 13px;
  border-radius: 50%; border: 2px solid var(--grey-400); background: var(--white);
}
.at-state-opt:hover { border-color: var(--grey-500); }
/* "Not started" chosen is a real answer, so it fills in like the others — but in
   grey: it claims nothing, and colouring it would make an unstarted duty look
   like a result. */
.at-state-none.selected {
  border-color: var(--grey-500); background: var(--grey-50); color: var(--grey-700);
}
.at-state-none.selected .at-state-dot { border-color: var(--grey-500); }
.at-state-none.selected .at-state-dot::after {
  content: ""; position: absolute; inset: 2px; border-radius: 50%; background: var(--grey-500);
}
.at-state-opt:focus-visible { outline: 2px solid var(--eu-blue); outline-offset: 2px; }
.at-state-done.selected {
  border-color: var(--risk-minimal); background: var(--risk-minimal-bg); color: var(--risk-minimal);
}
.at-state-done.selected .at-state-dot { border-color: var(--risk-minimal); }
.at-state-done.selected .at-state-dot::after {
  content: ""; position: absolute; inset: 2px; border-radius: 50%; background: var(--risk-minimal);
}
.at-state-incomplete.selected {
  border-color: var(--risk-limited); background: var(--risk-limited-bg); color: var(--risk-limited);
}
.at-state-incomplete.selected .at-state-dot { border-color: var(--risk-limited); }
.at-state-incomplete.selected .at-state-dot::after {
  content: ""; position: absolute; inset: 2px; border-radius: 50%; background: var(--risk-limited);
}
/* The row itself, so a card shows at a glance what is started and what is not. */
.at-ob-inc { background: var(--risk-limited-bg); }

/* Why a tick did not take. It borrows the row's own save-state line rather than
   adding a slot that is empty the rest of the time. */
.at-note-needed { color: var(--risk-limited); font-weight: 700; }
.at-note-needed-box { border-color: var(--risk-limited); }

/* Report: the third status, in the same column as Done and Outstanding. Amber,
   like the control that set it — never green, because it is not met. */
.rpt-done.inc { color: var(--risk-limited); font-weight: 700; }

/* ═══════════════════════════════════════════════
   FAQ (2026-08-29)
   Plain <details> rows. No JS: they open and close on their own, several can be
   open at once, and the browser's own find-in-page can reach a closed answer.
   The head reuses .guide2-head/-title/-sub so the two reference pages look like
   one thing rather than two.
   ═══════════════════════════════════════════════ */
.faq { max-width: 820px; }

.faq-group-title {
  font-size: 0.75rem; font-weight: 500; text-transform: uppercase; letter-spacing: 0.02em;
  color: var(--grey-500); margin: 26px 0 8px;
  font-family: var(--mono);
}
.faq-group-title:first-of-type { margin-top: 20px; }

/* One card per group, rows divided inside it — a card per question would make
   nineteen boxes on one screen. */
.faq-list {
  background: #fff; border: 1px solid var(--grey-200); border-radius: 16px;
  box-shadow: 0 1px 2px rgba(11, 27, 63, 0.04); overflow: hidden;
}

.faq-item { border-top: 1px solid var(--grey-200); }
.faq-item:first-child { border-top: none; }
.faq-item[open] { background: var(--grey-50); }

.faq-q {
  list-style: none; cursor: pointer; position: relative;
  padding: 16px 50px 16px 20px;
  font-size: 0.95rem; font-weight: 700; color: var(--grey-900); line-height: 1.5;
  font-family: var(--display);
  letter-spacing: -0.005em;
  transition: color 0.15s;
}
.faq-q::-webkit-details-marker { display: none; }
.faq-q:hover { color: var(--eu-blue); }
.faq-q:focus-visible { outline: 2px solid var(--eu-blue); outline-offset: -2px; }

/* The chevron is the only affordance saying a row opens, so it is drawn rather
   than left to the platform triangle, which differs per browser. */
.faq-q::after {
  content: ""; position: absolute; right: 22px; top: 50%;
  width: 8px; height: 8px; margin-top: -6px;
  border-right: 2px solid var(--grey-400); border-bottom: 2px solid var(--grey-400);
  transform: rotate(45deg); transform-origin: center;
  transition: transform .15s ease;
}
.faq-item[open] > .faq-q::after { transform: rotate(-135deg); margin-top: -2px; }
.faq-item[open] > .faq-q { color: var(--eu-blue-dark); }

.faq-a { padding: 0 50px 18px 20px; }
.faq-a p { font-size: 0.9rem; color: var(--grey-800); line-height: 1.65; margin: 0; }
.faq-a p + p { margin-top: 10px; }

.faq-foot {
  font-size: 0.85rem; color: var(--grey-600); line-height: 1.65;
  margin: 22px 0 0; padding-top: 14px; border-top: 1px solid var(--grey-200);
}

@media (max-width: 640px) {
  .faq-q { padding: 13px 40px 13px 14px; font-size: 0.9rem; }
  .faq-a { padding: 0 16px 14px 14px; }
}

/* ── My Account: the email preference (2026-08-29) ──────────────────────────
   Same shape as the sign-up tick box, so the two readings of one question look
   like one question. */
.acc-optin {
  display: flex; align-items: flex-start; gap: 11px;
  margin: 4px 0 0; padding: 11px 13px;
  border: 1px solid var(--grey-200); border-radius: 12px;
  background: #fff; cursor: pointer;
  transition: border-color 0.15s;
}
.acc-optin:hover { border-color: var(--eu-blue); }
.acc-optin input[type="checkbox"] {
  width: 17px; height: 17px; accent-color: var(--eu-blue); flex-shrink: 0; margin-top: 1px; cursor: pointer;
}
.acc-optin-text { font-size: 0.85rem; line-height: 1.5; color: var(--grey-800); }

/* Three buttons on every row of a long list: small, and they wrap under the text on a
   narrow screen rather than squeezing it. */
/* Under the text now (2026-10-07), so they can be bigger and clearer: blue outline until
   chosen, then filled. "Not sure" fills amber — an answer still to resolve. */
.fc-btns .fs-btn { font-size: 0.8rem; padding: 5px 14px; border: 1.5px solid var(--eu-blue); color: var(--eu-blue); }
.fc-btns .fs-btn:hover { background: var(--eu-blue-pale); }
.fc-btns .fs-btn.selected { background: var(--eu-blue); color: #fff; }
.fc-btns .fs-notsure.selected { background: var(--risk-limited-border); border-color: var(--risk-limited-border); color: var(--grey-900); }

/* ── Step 1: a tool folds away ────────────────────────────────────────────────
   The whole head is the control, so there is a target the size of the row rather
   than a caret you have to aim at. */
.fc-tool-head { cursor: pointer; user-select: none; }
/* A finished tool is one line, and it should look finished rather than merely quiet. */
.fc-ok { color: var(--risk-minimal); font-weight: 700; font-size: 0.8rem; }


/* ── Step 1: the fold control ─────────────────────────────────────────────────
   Words, not a caret, and pushed to the far right by margin-left:auto so it sits
   opposite the tool name instead of crowding it. It says what it will DO, which a
   ▸ cannot. The whole head is clickable; this is the visible affordance. */
.fc-toggle {
  margin-left: auto;
  flex: none;
  background: none;
  border: 1px solid var(--grey-300);
  border-radius: 999px;
  padding: 3px 12px;
  cursor: pointer;
  color: var(--eu-blue);
  font-size: 0.75rem;
  font-weight: 600;
  white-space: nowrap;
}
.fc-toggle:hover { background: var(--eu-blue-light); border-color: var(--eu-blue-light); }
.fc-toggle:focus-visible { outline: 2px solid var(--eu-blue); outline-offset: 2px; }



/* ── the three step ticks ─────────────────────────────────────────────────────
   ⚠ NOT PILLS, and not empty rings either. The tick is always drawn; only its
   COLOUR changes — grey while the step is outstanding, green once it is done. One
   shape filling in is read at a glance; three different shapes have to be decoded.
   The label is the step number, because the section heading below already says what
   each step is for. */
.ra-steps {
  display: flex;
  gap: 26px;
  flex-wrap: wrap;
  align-items: center;
}
/* The word in front of the ticks. It carries the summary; the ticks say which part.
   Only "Complete" takes the green — an assessment in progress is the normal state and
   should not be coloured as though something were wrong. */
.ra-prog {
  font-size: 0.9rem;
  color: var(--grey-700);
  margin-right: 4px;
  white-space: nowrap;
}
.ra-prog strong { font-weight: 700; }
.ra-prog-complete strong { color: var(--risk-minimal); }
.ra-stept {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--grey-600);
}
.ra-stept-box {
  width: 30px;
  height: 30px;
  flex: none;
  border-radius: 50%;
  background: var(--grey-300);
  color: #fff;
  display: grid;
  place-items: center;
  font-size: 1rem;
  font-weight: 700;
  line-height: 1;
  transition: background-color 160ms ease, color 160ms ease;
}
.ra-stept.done { color: var(--risk-minimal); }
.ra-stept.done .ra-stept-box { background: var(--risk-minimal); }
@media (prefers-reduced-motion: reduce) { .ra-stept-box { transition: none; } }
@media (max-width: 560px) { .ra-steps { gap: 16px; } }


/* ═══ Actions Tracker: the feature rail and the per-feature panel ═══════════
   One panel per AI FEATURE, one note per obligation ON that feature. Article 26
   attaches its duties to each system: oversight (26(2)), input data (26(4)),
   logs (26(6)), informing affected workers (26(7)) and informing the people
   subject to a decision (26(11)) can each be true of one feature and false of
   the next one in the same tool. See renderAtGrid() in dashboard.js. */

/* ── the progress bar, used at three sizes and never with a percentage ──────
   "4 of 10" is the honest figure; a percentage of ten items invents precision
   the number does not have and makes 1 look like 10%. The bar shows the shape,
   the words carry the count. */
.at-prog {
  display: block; height: 6px; border-radius: 999px;
  background: var(--grey-200); overflow: hidden;
}
.at-prog-bar {
  display: block; height: 100%; border-radius: 999px;
  background: var(--eu-blue); transition: width 0.18s ease;
}
.at-prog-bar.full { background: var(--risk-minimal); }
.at-prog.sm { height: 4px; }

/* Under the feature's name: where this one feature stands, on its own. */
/* ⛔ .at-feat-prog-row IS GONE (user, 2026-09-05). The panel repeated the figure
   the rail already shows against every feature, including the one on screen — the
   same number twice, a few hundred pixels apart. The rail is where progress is
   read; the panel is where the work is done. */

/* ── the rail ───────────────────────────────────────────────────────────── */
/* ⭐ THE HEADING IS OUTSIDE THIS BOX (user, 2026-09-06). It was the first row
   inside it, which put this card's top edge level with the obligations HEADING
   and a heading's height above the obligations CARD. The rail now opens with the
   same .at-section-head the left column uses, so the two white panels start at
   the same y by construction — no offset to keep in step.
   ⚠ A LIGHT GROUND, NOT WHITE: the feature rows are cards now, and a white card
   on a white panel has only its border to show for it.
   ⚠ grey-100, NOT grey-50 (user, 2026-09-06: the cards should "stand out a bit
   more than now when not selected"). grey-50 is #F8F9FA — three per cent off
   white, so a white card on it was separated by almost nothing and the border was
   doing all the work alone. The lever that matters here is the CONTRAST BETWEEN
   THE CARD AND ITS GROUND, not the weight of the card's own edge: grey-200 and
   grey-300 differ by one step and changing between them is barely visible. */
.at-feat-nav-inner {
  background: var(--grey-100);
  border: 1px solid var(--grey-200);
  border-radius: 14px;
  /* ⭐ THE TOP IS 2px, DELIBERATELY UNEVEN (user, 2026-09-07: "move cards in right
     panel up, so they level with mid panel obligation"). Both columns start at the
     same y — same .at-section-head, same margins — so everything holding the first
     card down was inside this box: 12px of padding plus its border, against an
     obligations card whose own head starts 11px in. That put the first card a clear
     13px below the card it sits beside, which is exactly far enough to read as a
     mistake and not far enough to read as a choice.
     ⚠ SO TOP AND BOTTOM ARE NOT MEANT TO MATCH. Evening them up is what breaks the
     alignment; the pair of columns is the thing being lined up, not the inside of
     this box. 2px rather than 0 keeps a sliver of ground above the first card so it
     still reads as sitting IN the panel rather than replacing its edge. */
  /* ⭐ 8px SIDES, NOT 12 (user, 2026-09-07: "move cards a bit to the left"). This is
     a 272px column and every pixel of padding comes off the card, which is where the
     feature name lives. The box still reads as a box — the ground colour does that,
     not the size of its margin. */
  padding: 2px 8px 10px;
  max-height: calc(100vh - 160px);
  /* ⛔⛔ overflow-x: hidden IS DELIBERATE AND MUST STAY (user, 2026-09-07: "right
     panel has still some horizontal slider which I dont like"). Setting overflow-y
     alone does NOT leave the other axis alone: CSS computes a `visible` overflow-x
     to `auto` the moment its partner is not visible, so the box grew a horizontal
     scrollbar of its own for a few pixels of overshoot. There is nothing to scroll
     to sideways in a rail — the tool name ellipsises, the feature name clamps to two
     lines — so anything reaching past the edge is a bug to fix at its source, not
     something to offer the reader a bar for. */
  overflow-y: auto;
  overflow-x: hidden;
  /* ⭐ THE GUTTER IS RESERVED WHETHER OR NOT THE BAR IS THERE. Without this, the
     scrollbar appearing takes ~15px off every card the moment the list grows past
     the box — so the rail re-lays itself out mid-session and a name that fitted
     stops fitting. Reserved, the cards are one width at all times. */
  scrollbar-gutter: stable;
}
/* ⛔ .at-feat-nav-head / .at-feat-nav-k ARE GONE (2026-09-06) — the in-box heading
   row. The title is an .at-section-k above the box now; only the count survives,
   and it sits in that heading beside it. */
.at-feat-nav-n {
  flex: none; min-width: 20px; text-align: center;
  font-size: 0.72rem; font-weight: 500; color: var(--grey-700);
  background: var(--grey-100); border-radius: 999px; padding: 1px 7px;
  font-family: var(--mono);
}
/* ⛔ .at-feat-nav-overall IS GONE (2026-09-07) — the bar and "n of m recorded in
   all" that sat above the cards. The meta card at the top of the screen says the
   same thing off the same filter, and this one counted one row fewer. Nothing in
   any .js writes the class. See renderAtGrid for the full reasoning. */
/* The count keeps its chip but now rides in the heading outside the box, so it
   needs to hold its own against an uppercase title rather than a grey label. */
.at-section-head .at-feat-nav-n { margin-left: auto; }
/* ⚠ THE GAP IS WHAT MAKES THEM CARDS. At 4px the rows read as a list with borders
   on it; the space between is the thing the eye uses to separate one card from the
   next, so it is deliberately larger than the padding inside them.
   ⚠ margin-top IS 0 NOW: it cleared the overall bar that used to sit above, and
   with that gone it was just a gap at the top of the box holding the cards down. */
.at-feat-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }

/* ── "Where this came from", in the corner of the card it explains ────────────
   ⚠ THE MARK IS A SIBLING OF THE CARD, positioned over it. The card is a <button>
   and a button may not contain another one, so the ⓘ hangs off the <li> instead.
   That also means a click on it never reaches the card's own handler — there is no
   stopPropagation() here to be lost in a later edit, unlike the Step 1 fold.
   ⭐ THE ROOM IS RESERVED ONLY WHERE THE MARK EXISTS (.has-src), and on whichever
   row is TOP — the risk pill's, since 2026-09-07. Padding every card would leave a
   hole on the ones with nothing to explain, and a hole in a 272px column is more
   noticeable than the mark. */
.at-feat-item { position: relative; }
.at-feat-info { position: absolute; top: 9px; right: 10px; margin-left: 0; }
.at-feat-item.has-src .at-feat-btn-tier { padding-right: 22px; }

/* A whole button, not a link with a dot: the target is the row, and the row
   carries three facts (tool, feature, progress) that all have to stay legible
   in 240px. The feature is the subject, so the tool reads as a kicker above it
   — the same order the panel heading uses.
   ⭐ AND EACH ONE IS A SMALL CARD (user, 2026-09-06: "make individual cards more
   distinguishable so they look like small cards"). They were transparent with a
   transparent border, so an unselected feature had no edge at all and four of them
   ran together as one block of text — the rail is a list of THINGS, and each thing
   carries four facts of its own (tool, feature, risk level, progress).
   ⚠ THE BORDER AND THE GROUND DO THIS, NOT A HEAVY SHADOW. A drop shadow on every
   row in a 272px column reads as noise at this size; a real edge on a lighter
   ground is what separates them. */
.at-feat-btn {
  display: grid; gap: 3px; width: 100%; text-align: left;
  padding: 10px 11px; cursor: pointer;
  background: var(--white); border: 1px solid var(--grey-300); border-radius: 12px;
  box-shadow: 0 1px 2px rgba(11, 27, 63, 0.06);
  font: inherit; color: var(--grey-800);
  transition: border-color 0.15s, box-shadow 0.15s;
}
/* Hover lifts it further rather than changing its colour — the card is already a
   card, so the only thing left to say is that it is the one under the pointer. */
.at-feat-btn:hover { border-color: var(--eu-blue-light); box-shadow: 0 4px 12px -4px rgba(11, 27, 63, 0.18); }
/* ⚠ THE SELECTED CARD IS THE ONE ON SCREEN, so it is stated twice — filled AND
   edged — because in a scrolling column the fill alone can be off-screen while the
   panel it belongs to is not. */
.at-feat-btn.selected {
  background: var(--eu-blue-light); border-color: var(--eu-blue);
  box-shadow: 0 0 0 3px rgba(0, 51, 153, 0.10);
}
.at-feat-btn-sw { font-size: 0.72rem; color: var(--grey-600); }
.at-feat-btn.selected .at-feat-btn-sw { color: var(--eu-blue-dark); }
/* A feature name can be a whole declared use — 341 characters at the longest.
   In a 240px rail that has to be clamped, and the panel heading shows it whole.
   ⚠⚠ min-width: 0 IS LOAD-BEARING, and its absence is what cut the cards off on
   the right (user, 2026-09-07). This is a FLEX ITEM inside .at-feat-btn-row, and a
   flex item's default min-width is AUTO — it refuses to shrink below its longest
   unbreakable word. So a feature name carrying a long word (or a URL-ish product
   term) pushed the row wider than the card and the overflow was clipped by the
   scrolling box around it. The line-clamp above does NOT prevent this: it limits
   HEIGHT, and says nothing about how narrow the box may get.
   ⭐ It showed up when the list grew long enough to scroll, because the scrollbar
   takes width off every card and made a name that just fitted stop fitting —
   which is why it read as "caused by the slider". The slider only revealed it. */
/* ⭐ SMALLER AND LIGHTER, AND THREE LINES (user, 2026-09-07: "I find font type of
   individual ai features too big or bold, some dont even fit on the card"). It was
   0.82rem/700 clamped to two lines, in about 145px of usable width once the 62px
   label column is taken off — roughly forty characters before it cut. At 0.78rem/600
   over three lines it holds closer to eighty, which is where the real feature names
   sit. ⚠ 600, NOT 700: the weight was doing the work of saying "this is the subject
   of the card", and the label beside it already says that — bold at this size mostly
   costs width. The panel heading still shows the name whole and unclamped. */
.at-feat-btn-feat {
  min-width: 0; overflow-wrap: anywhere;
  font-size: 0.8rem; font-weight: 600; line-height: 1.35;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
  overflow: hidden;
}
.at-feat-btn-prog { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 8px; margin-top: 3px; }
.at-feat-btn-n { font-size: 0.72rem; color: var(--grey-600); white-space: nowrap; }
.at-feat-btn.complete .at-feat-btn-n { color: var(--risk-minimal); font-weight: 700; }
/* ⛔ .at-expand-all and .at-ob-body ARE GONE (2026-09-06) — "Open all / Collapse
   all" and the block it opened. Ten explanations stacked open made a feature
   unreadable, which is why the control existed; ten Act quotes would be worse,
   which is why they moved to a panel that shows one at a time. */
/* ⛔ .at-note-flag / .at-note-mark ARE GONE (user, 2026-09-05). A mark saying
   "there is a note in here" was a ✎, then a word chip, and either way it was a
   second thing competing for a line whose subject is the obligation. */

/* ── The tracker is wider than the rest of the app ──────────────────────────
   ⚠ SCOPED TO THE BUILDER, deliberately. .dash-content caps every page at
   1040px; widening that would stretch the library, the assessments, the report
   and My Account along with it. This screen alone carries a feature panel AND a
   rail beside it, so this screen alone gets the room. */
.at-wide { width: 100%; }
@media (min-width: 1200px) {
  .dash-content:has(#atBuilderView.at-wide:not(.hidden)) { max-width: 1320px; }
}

/* The feature's risk level, on its button. Small, because the button's subject
   is the feature and the level is a fact about it — the same relationship the
   panel heading has with its own pill. */
.risk-pill.sm { font-size: 0.6rem; padding: 1px 6px; letter-spacing: 0.02em; }
/* ⛔⛔ THE RISK PILL HAS ITS OWN LINE, ALWAYS — see .at-feat-btn-tier below. It used
   to share this row, sitting top-right beside the tool name, and it did not fit.
   Do the arithmetic before putting it back: the pill is nowrap and uppercase, and
   the longest level is "Transparency obligation" — 23 characters, about 159px at
   .risk-pill.sm. The row beside it cannot go below 69px (.at-feat-btn-k is a hard
   62px). 69 + 8 + 159 = 236px against roughly 215px of card, so a transparency
   feature pushed its own top row past the right edge and took the corner — and the
   ⓘ that lives in it — out of sight behind the box's clip.
   ⛔ AND WRAPPING WAS NOT THE ANSWER (user, 2026-09-07: "some risk pills are in the
   right corner, some under sw name depending on the lenght os sw name"). Letting it
   wrap only when it had to made the pill's position depend on how long the vendor's
   name happened to be — so the same fact sat in two different places down one
   column, and the eye had to hunt for it on every card. A list of cards is read by
   scanning the same spot on each one; a rule that holds sometimes is worse than
   either rule held always.
   ⚠ min-width: 0 STAYS. It is why the tool name ellipsises instead of pushing the
   card wide: a flex item will not shrink below its longest word without it. */
.at-feat-btn-top { display: flex; align-items: center; min-width: 0; }
.at-feat-btn-top .at-feat-btn-sw { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.at-feat-btn-top .at-feat-btn-row { flex: 1 1 auto; }
/* ⭐ THE LEVEL LEADS THE CARD (user, 2026-09-07: "can we place risk on top, above
   software name"). It is the first line, on its own, above both names — so the
   column can be scanned by severity down a single left edge without reading a word
   of any card. It sat between the names and the progress for one round; that read
   what → how serious → how far, which is the wrong order for a list whose whole
   sort is by risk (atFeatures orders on TIER_ORDER, worst first).
   ⚠ FULL CARD WIDTH IS WHAT KEEPS IT ON ONE LINE. "Transparency obligation" is
   about 159px and the pill cannot wrap; sharing a row with anything is what put it
   off the right edge in the first place. */
.at-feat-btn-tier { display: flex; margin-bottom: 3px; }
.at-feat-btn-tier .risk-pill { flex: none; }
/* The same guard one level up: a grid item's default min-width is auto too, so the
   card itself would grow past its column rather than let a child shrink. */
.at-feat-item, .at-feat-btn, .at-feat-btn-prog, .at-prog { min-width: 0; }
/* The panel says the level too, beside the name it belongs to. */
.at-card-head .risk-pill { flex: none; }


/* ═══ Actions Tracker, second pass (2026-09-05) ═════════════════════════════ */

/* ── A named block, twice: the duties on everyone, then the duties on this
   feature. The heading used to sit INSIDE the feature card, which left the
   AI-literacy card above it with no title at all — it read as a cutting from
   somewhere else. Both blocks are now introduced the same way. */
.at-section-head {
  display: flex; align-items: baseline; gap: 8px;
  margin: 22px 0 8px;
}
/* ⚠ THE HEADING MUST NOT GROW (user, 2026-09-05). It had flex: 1 1 auto, so it
   stretched across the row and carried the ⓘ with it to the far edge, where the
   icon read as belonging to "Open all" rather than to the title it explains.
   The title sizes to its words, the ⓘ follows it, and the auto margin below
   pushes Open all to the other end. */
.at-section-k {
  margin: 0; flex: 0 1 auto; min-width: 0;
  font-size: 1.1rem; font-weight: 700; color: var(--grey-900);
  text-transform: none; letter-spacing: -0.01em;
  font-family: var(--display);
}
/* ⚠ THE SAME MARK AS THE NOTE ABOVE IT (user, 2026-09-05): a FILLED blue disc
   with a white i, not the ⓘ glyph — which renders as a thin outline on Windows
   and reads as faint rather than as a mark. Same shape as .at-intro-ico; this
   one is a BUTTON, because it opens a panel rather than decorating a sentence. */
.at-section-info {
  flex: none; margin-right: auto; margin-left: 0;
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; padding: 0;
  border: none; border-radius: 50%; cursor: pointer;
  background: var(--eu-blue); color: #fff;
  font-size: 0.68rem; font-weight: 700; font-style: italic;
  font-family: Georgia, 'Times New Roman', serif; line-height: 1;
}
.at-section-info:hover { background: var(--eu-blue-dark); color: #fff; }

/* ── What is what. A feature name can BE a whole declared use, so the tool and
   the feature ran together as one sentence with nothing saying which was which.
   Same two labels the report card uses for the same two facts. */
.at-card-row { display: flex; gap: 10px; align-items: baseline; padding: 1px 0; }
.at-card-k {
  flex: 0 0 101px; white-space: nowrap;
  font-size: 0.72rem; font-weight: 500; text-transform: uppercase; letter-spacing: 0.02em;
  color: var(--grey-500); line-height: 1.65;
  font-family: var(--mono);
}
.at-card-head .at-card-names { flex: 1 1 auto; }

/* ⛔ THE FEATURE NAME BROKE MID-WORD ON A PHONE — "HiredScor / e" (found 2026-09-18,
   first phone-width check). A 101px label column beside the value is right on a wide
   card and leaves about 110px on a 390px screen. The label goes ABOVE its value below
   560px, which is what a label does when there is no room beside it. */
@media (max-width: 560px) {
  .at-card-row { flex-direction: column; align-items: stretch; gap: 0; }
  .at-card-k { flex: none; }
}

/* The same pair in the rail, smaller so both still fit a 300px column. */
.at-feat-btn-row { display: flex; gap: 7px; align-items: baseline; min-width: 0; }
.at-feat-btn-k {
  flex: 0 0 83px; white-space: nowrap;
  font-size: 0.72rem; font-weight: 500; text-transform: uppercase; letter-spacing: 0.02em;
  color: var(--grey-500); line-height: 1.8;
  font-family: var(--mono);
}
.at-feat-btn.selected .at-feat-btn-k { color: var(--eu-blue); }


/* ── AI literacy is built from the obligation row now, so its note sits inside
   the same box as everything else. Its blue is kept: it is not a risk level. */
.at-card-lit { border-left-color: var(--eu-blue); }
.at-ob-lit .at-duty-label { font-weight: 700; }
/* ⭐ ONE MARK FOR EVERY OBLIGATION (2026-09-06). This was .at-literacy-info, worn
   by the single row that already opened the Act in a panel. Every obligation does
   that now, so the rule is shared rather than copied — the same filled blue disc
   with a white i as .at-section-info and .at-intro-ico.
   ⚠ A FILLED DISC, never the ⓘ GLYPH: ⓘ renders as a thin outline on Windows and
   reads as faint rather than as a mark, the same reason 🗒 had to go in August.
   ⛔ The sidebar's ⓘ is deliberately NOT part of this set — it belongs to the nav
   glyphs (⌂ ▤ ✓ ☰ ▦ ◉ ? ⚙), which are a different family. */
.at-ob-info {
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; padding: 0; margin-left: 6px;
  border: none; border-radius: 50%; cursor: pointer;
  background: var(--eu-blue); color: #fff;
  font-size: 0.68rem; font-weight: 700; font-style: italic;
  font-family: Georgia, 'Times New Roman', serif; line-height: 1;
  vertical-align: middle;
}
.at-ob-info:hover { background: var(--eu-blue-dark); color: #fff; }
/* ⛔ .at-literacy-tag IS GONE ENTIRELY (2026-09-06) — both copies of it. The
   literacy row's "applies to all" wears .at-duty-tag now, the same tag as the date
   beside it, so the two facts on that row cannot drift apart in style. Nothing in
   any .js still writes the old class. */

/* The note box has no heading: it is plainly a box, and the prompt inside it
   already names the facts that duty wants — so the word "Notes" leads the prompt
   instead of sitting in a line above it. The label survives only for screen
   readers, as aria-label on the field itself. */
/* ⭐ The 6px left indent is NOT vestigial (checked 2026-09-14): it matches
   .at-ob-line's padding-left and .at-ob-ext-line's margin, so the note starts where
   the obligation title and the explanation box above it start. Keep them in step. */
.at-ob-note { margin: 10px 0 0 6px; }
/* The info mark leading the note: a FILLED blue disc with a white i, not the ⓘ
   glyph — that renders as a thin outline on Windows and reads as faint rather
   than as a mark. Same shape as .info-ico in My Account, in the app's blue.
   Decorative, not a control — the link beside it is the thing you click, so it
   is aria-hidden rather than a second tab stop that does nothing. */
.at-intro-ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  flex: none;
  margin-right: 8px;
  border-radius: 50%;
  background: var(--eu-blue);
  color: #fff;
  font-size: 0.68rem;
  font-weight: 700;
  font-style: italic;
  font-family: Georgia, 'Times New Roman', serif;
  line-height: 1;
  vertical-align: -3px;
}

/* ⚠ THE NOTE IS OUT OF THE COLLAPSE (user, 2026-09-05). It is the point of this
   screen — the only place the report says HOW a duty is met — and behind a
   collapse it was one click away from never being written. What collapses now is
   the EXPLANATION, which is read once. Field size is unchanged: two rows. */
.at-ob .at-ob-note { margin: 8px 0 2px 6px; }
/* ⛔ .at-what-gap IS GONE (2026-09-06). It reserved the Expand column on the
   literacy row so its answers lined up with every other row's. No row has an
   Expand button now, so the column itself went and the spacer with it. */
.at-lit-note { padding: 0; }
/* The AI-literacy sentence lines up with the words "AI literacy" above it, not
   with the 36px indent the badge explanations use on an ordinary obligation row.
   6px matches .at-ob-line's own padding-left, which is what sets where the title
   starts. ⚠ SCOPED TO THE LITERACY ROW: the same class carries the external-regime
   and provider-owed explanations elsewhere, where the indent is deliberate. */
/* ⛔ The literacy row no longer needs its own override — 6px IS the rule now. */

/* A link that leaves for another window says so. Same arrow the Act links use. */
.at-intro-new { color: var(--eu-blue); font-size: 0.8rem; }


/* ═══════════════════════════════════════════════════════════════════════════
   TOUCH SIZES — phone only (added 2026-09-18, first phone-width check)

   On a phone a finger needs about 40px; a mouse pointer needs none of it. Every
   control below was between 16px and 32px tall, which is right for a desktop
   toolbar and wrong for a thumb — and the two worst offenders are the two most
   pressed controls in the app: the on/off/not-sure buttons in Step 1 (87 of them
   on the worked example alone) and the tracker's not-started/incomplete/complete.

   ⚠ THIS BLOCK LIVES AT THE END OF THE FILE ON PURPOSE. Every rule here overrides
   one defined further up with the same specificity, so it only wins by coming
   last. Moving it up the file silently undoes it.

   ⛔ NOT TOUCHED, because they are already big enough: the tick boxes in My Account
   look 18px but each sits inside a <label> wrapping the whole option card, so the
   target is the card. Nor the links inside a sentence — they are read, not aimed at,
   and padding them out would break the line spacing of the prose around them.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 560px) {
  /* Step 1 — is this feature on, off, or not known */
  /* ⚠ .fc-btns .fs-btn further up carries an extra class, so a plain .fs-btn here
     loses to it however late it comes. Both, or the buttons stay 25px. */
  .fs-btn,
  .fc-btns .fs-btn { padding: 12px 10px; }
  /* And let the three of them wrap. .fc-btns is flex: none, so on a 320px screen the
     roomier buttons ran off the edge instead of going onto a second line. */
  .fc-btns { flex: 1 1 100%; margin-left: 0; }
  /* Actions Tracker — how far this obligation has got */
  .at-state-opt { padding: 12px 12px 12px 10px; }
  /* Library — take this tool out again */
  .lib-item .sw-remove-btn { padding: 10px 14px; }
  /* Step 1 / Library — show or hide a tool's feature list */
  .fc-toggle { padding: 12px 14px; }
  /* Delete / View on the record lists */
  .btn-sm { height: 40px; padding: 0 16px; }
  /* Tracker — read more of a long explanation */
  .at-see-more { padding: 10px 6px; }
  /* The ⓘ marks stay 16px to the eye — the padding grows the target around them,
     and a transparent border is what carries it on a button with a round
     background, since padding would inflate the blue circle itself. */
  .at-ob-info, .at-section-info {
    box-sizing: content-box;
    border: 12px solid transparent;
    background-clip: padding-box;
    margin: -12px -12px -12px -6px;
  }
  /* Rating stars in the feedback window */
  .fb-star { padding: 6px 7px; }
  /* Step 2 — the pencil and cross on a chosen feature. Same idea as the ⓘ marks:
     the glyph keeps its size, the padding grows the target around it. */
  .uft-icon { padding: 10px 8px; }
}

/* ── The admin red dot (phase72) ─────────────────────────────────────────────
   On the sidebar's Admin link when something new needs the admin. Same colour and
   size as the admin page's own tab dots (.admin-tab-dot), pushed to the row's end. */
.dash-nav-dot {
  width: 8px; height: 8px; flex: none;
  margin-left: auto;
  border-radius: 50%;
  background: var(--risk-high);
}

/* NO-LINK CARDS (2026-10-06): the vendor's terms ban linking (ADP, LinkedIn), so the card
   says so once and each row carries "Where to look" text instead of a link. */
.sw-panel-nolink, .rpt-inv-nolink {
  font-size: 0.8rem; color: var(--grey-700, #444);
  background: var(--grey-50, #f7f7f8); border-left: 3px solid var(--grey-300, #ccc);
  padding: 6px 10px; margin: 0 0 8px; border-radius: 4px;
}
.rpt-inv-nolink { margin-top: 8px; }
.fc-src-look { font-size: 0.75rem; color: var(--grey-700, #444); }

/* ── MY PLACE · AI LITERACY (2026-10-10, admin only for now) ────────────────
   From local/my-place-mockup.html, which the user approved. */
.dash-nav-sub {
  display: flex; flex-direction: column; gap: 2px;
  margin: 2px 0 6px 30px; padding-left: 10px; border-left: 1px solid var(--grey-200);
}
.dash-nav-sub.hidden { display: none; }
.dash-nav-subitem {
  display: flex; align-items: center; font-size: 0.84rem; color: var(--grey-700);
  padding: 6px 10px; border-radius: 8px; text-decoration: none;
}
a.dash-nav-subitem:hover { background: var(--grey-100); color: var(--grey-900); }
.dash-nav-subitem.active { background: var(--eu-blue-light); color: var(--eu-blue); font-weight: 600; }

.mp-subtitle { font-family: var(--display); font-size: 1.15rem; font-weight: 700; color: var(--grey-900); margin: 4px 0 12px; }
.mp-lead { font-size: 0.84rem; color: var(--grey-600); margin: -6px 0 14px; }
.mp-stat-line { font-size: 0.8rem; color: var(--grey-700); margin-top: 6px; }
.mp-stat-line b { color: var(--grey-900); }
.ra-status.mp-open   { background: var(--risk-minimal-bg); color: var(--risk-minimal); }
.ra-status.mp-closed { background: var(--risk-unsure-bg); color: var(--risk-unsure); }

.mp-card { background: var(--white); border: 1px solid var(--grey-200); border-radius: 12px; padding: 18px 20px; margin-bottom: 14px; }
.mp-k { font-size: 0.72rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--eu-blue-dark); margin-bottom: 8px; }
.mp-row { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
.mp-row .input { flex: 1; min-width: 220px; }
.mp-row .input[readonly] { background: var(--grey-50); color: var(--grey-700); }
.mp-hint { font-size: 0.78rem; color: var(--grey-600); margin-top: 8px; }
.mp-hint b { color: var(--grey-900); }
.mp-copied { font-size: 0.78rem; color: var(--risk-minimal); font-weight: 600; display: none; }
.mp-err { color: var(--risk-high); font-size: 0.8rem; margin-top: 8px; }
.mp-err:empty { display: none; }

.mp-tiles { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin: 4px 0 14px; }
.mp-tile { background: var(--white); border: 1px solid var(--grey-200); border-radius: 12px; padding: 14px 16px; }
.mp-tile-n { font-family: var(--display); font-size: 1.9rem; font-weight: 700; color: var(--grey-900); line-height: 1.1; }
.mp-tile-n small { font-size: 0.95rem; color: var(--grey-500); font-weight: 600; }
.mp-tile-n.mp-tile-date { font-size: 1.35rem; padding: 6px 0 4px; }
.mp-tile-l { font-size: 0.78rem; color: var(--grey-600); margin-top: 4px; }
.mp-tile.ok .mp-tile-n { color: var(--risk-minimal); }

.mp-table-card { padding: 8px 10px; overflow-x: auto; }
.mp-table { width: 100%; border-collapse: collapse; font-size: 0.84rem; }
.mp-table th { text-align: left; font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.04em; color: var(--grey-500);
  font-weight: 600; padding: 8px 10px; border-bottom: 1px solid var(--grey-200); }
.mp-table td { padding: 10px; border-bottom: 1px solid var(--grey-100); color: var(--grey-800); }
.mp-table tr:last-child td { border-bottom: 0; }
.mp-score { font-weight: 700; }
.mp-bar { display: inline-block; width: 70px; height: 6px; border-radius: 3px; background: var(--grey-100);
  vertical-align: middle; margin-left: 8px; overflow: hidden; }
.mp-bar i { display: block; height: 100%; background: var(--eu-blue-mid); }
.mp-muted { color: var(--grey-500); }
@media (max-width: 900px) { .mp-tiles { grid-template-columns: 1fr; } }
/* Section 3 of a course, highlighted (user, 2026-10-10) — the same framed panel as Step 3's
   "Status of AI features" (.stl-panel): pale blue, blue top border. */
.mp-results {
  border: 1px solid var(--eu-blue-light); border-top: 4px solid var(--eu-blue);
  border-radius: 16px; padding: 16px 16px 12px; background: var(--eu-blue-pale); margin-top: 22px;
}
.mp-results .mp-table-card { margin-bottom: 4px; }
.mp-table td.mp-del { width: 1%; text-align: right; }
/* Icons on course sections 1 and 2 (user, 2026-10-10): Lucide line icons, like the menu. */
.mp-k { display: flex; align-items: center; gap: 8px; }
.mp-k-ico { display: inline-flex; width: 20px; height: 20px; color: var(--eu-blue); }
.mp-k-ico svg { width: 100%; height: 100%; }
/* Course section headings bigger (user, 2026-10-10): 0.72rem → 0.95rem, icons to match. */
.mp-k { font-size: 0.95rem; margin-bottom: 12px; }
.mp-k-ico { width: 24px; height: 24px; }

/* ═══════════════════════════════════════════════════════════════
   MY PLACE · AI USE RULES (2026-10-14) — from local/ai-use-rules-mockup.html (approved).
   Everything is under #page-airules so nothing leaks into the rest of the app.
   ═══════════════════════════════════════════════════════════════ */
.dash-content:has(#page-airules:not(.hidden)) { max-width: none; }   /* full width (user, 2026-10-13) */
#page-airules .ur-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; flex-wrap: wrap; margin-bottom: 6px; }
#page-airules .ur-head h2 { font-family: var(--display); font-size: 1.35rem; color: var(--grey-900); margin: 0 0 4px; }
#page-airules .ur-lead { font-size: .88rem; color: var(--grey-600); margin: 0 0 12px; }
#page-airules .ur-head > div:first-child { flex: 1; }
#page-airules .ur-tabs { display: flex; gap: 6px; margin: 18px 0 16px; border-bottom: 1px solid var(--grey-200); }
#page-airules .ur-tabs button { font: inherit; font-size: .9rem; font-weight: 600; color: var(--grey-600); background: none; border: 0; border-bottom: 3px solid transparent; padding: 10px 14px; cursor: pointer; }
#page-airules .ur-tabs button[aria-selected="true"] { color: var(--eu-blue); border-bottom-color: var(--eu-blue); }
#page-airules .ur-chooser, #page-airules .ur-release { padding: 16px 18px; margin: 0 0 14px; }
#page-airules .ur-release { margin-top: 16px; }
#page-airules .ur-chooser p, #page-airules .ur-release p { margin: 0 0 8px; font-size: .9rem; }
#page-airules .ur-chooser-btns { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; }
#page-airules .ur-docline { display: flex; align-items: center; gap: 10px; margin: 6px 0 0; }
#page-airules .ur-saved { font-size: .8rem; color: var(--risk-minimal); font-weight: 600; }
#page-airules .ur-ex-note { margin: 10px 0 0; max-width: none; }

/* sections: white cards with a blue left edge and a tinted header band (user, 2026-10-13) */
#page-airules .ur-sec { background: #fff; border: 1px solid var(--grey-300); border-left: 4px solid var(--eu-blue); border-radius: 12px; padding: 18px 20px; margin-bottom: 24px; box-shadow: 0 2px 8px rgba(11,27,63,.07); }
#page-airules .ur-sec-h { display: flex; align-items: center; gap: 10px; margin: -18px -20px 0 -20px; padding: 14px 20px 2px; background: var(--eu-blue-pale); border-radius: 0 11px 0 0; }
#page-airules .ur-n { width: 26px; height: 26px; border-radius: 50%; background: var(--eu-blue); color: #fff; font-weight: 700; font-size: .8rem; display: grid; place-items: center; flex: none; }
#page-airules .ur-sec-h h3 { font-family: var(--display); font-size: 1.02rem; color: var(--grey-900); margin: 0; }
#page-airules .ur-sub { font-size: .82rem; color: var(--grey-600); margin: 0 -20px 16px -20px; padding: 2px 20px 12px 56px; background: var(--eu-blue-pale); border-bottom: 1px solid var(--eu-blue-light); }
#page-airules .ur-opt { font-weight: 400; color: var(--grey-500); }

/* small ⓘ next to the thing it explains */
#page-airules .ur-tipw { position: relative; display: inline-block; vertical-align: middle; margin-left: 2px; }
#page-airules .ur-i { border-radius: 50%; border: 1.3px solid var(--eu-blue-mid); color: var(--eu-blue-mid); background: #fff; font: italic 700 .62rem/1 Georgia, serif; cursor: pointer; flex: none; width: 17px; height: 17px; padding: 0; }
#page-airules .ur-i[aria-expanded="true"] { background: var(--eu-blue-mid); color: #fff; }
#page-airules .ur-pop { display: none; position: absolute; z-index: 30; top: calc(100% + 6px); left: -8px; width: 280px; background: #fff; border: 1px solid var(--eu-blue-light); border-radius: 10px; box-shadow: 0 8px 22px rgba(11,27,63,.14); padding: 10px 12px; font-size: .8rem; font-weight: 400; line-height: 1.45; color: var(--grey-800); text-transform: none; letter-spacing: 0; text-align: left; white-space: normal; }
#page-airules .ur-pop-r { left: auto; right: -8px; }
#page-airules .ur-tipw.open .ur-pop { display: block; }

/* section 1 */
#page-airules .ur-grid-biz { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
#page-airules .ur-row2 { grid-column: 1 / -1; display: grid; grid-template-columns: 2fr 1fr 1fr; gap: 12px; }
#page-airules .ur-f-wide { grid-column: 1 / -1; }
@media (max-width: 900px) { #page-airules .ur-grid-biz, #page-airules .ur-row2 { grid-template-columns: 1fr; } }
#page-airules .ur-f label { display: block; font-size: .76rem; font-weight: 600; color: var(--grey-700); margin-bottom: 4px; }
#page-airules .ur-f .input { width: 100%; box-sizing: border-box; }
#page-airules .ur-from { font-size: .74rem; color: var(--grey-500); margin-top: 3px; }
#page-airules .ur-months { display: flex; align-items: center; gap: 8px; }
#page-airules .ur-months .input { width: 90px; }
#page-airules .ur-months span { color: var(--grey-700); }
#page-airules .ur-comment { width: 100%; box-sizing: border-box; font: inherit; font-size: .9rem; line-height: 1.5; resize: vertical; min-height: 96px; }

/* tables */
#page-airules .ur-table { width: 100%; border-collapse: collapse; font-size: .84rem; }
#page-airules .ur-table th { text-align: left; font-size: .7rem; text-transform: uppercase; letter-spacing: .04em; color: var(--grey-500); font-weight: 600; padding: 8px; border-bottom: 1px solid var(--grey-200); vertical-align: bottom; }
#page-airules .ur-table td { padding: 9px 8px; border-bottom: 1px solid var(--grey-100); color: var(--grey-800); vertical-align: top; }
#page-airules .ur-table tr:last-child td { border-bottom: 0; }
#page-airules .ur-table td.c, #page-airules .ur-table th.c { text-align: center; }
#page-airules .ur-table select { font: inherit; font-size: .8rem; padding: 4px 6px; border: 1px solid var(--grey-300); border-radius: 6px; background: #fff; width: 100%; max-width: 240px; }
#page-airules .ur-table small { display: block; color: var(--grey-500); font-size: .74rem; margin: 4px 0 0 2px; }
#page-airules .ur-table td > .input { width: 100%; box-sizing: border-box; font-size: .86rem; padding: 6px 8px; }
#page-airules a.ur-add { font-size: .82rem; color: var(--eu-blue); font-weight: 600; margin-top: 10px; display: inline-block; text-decoration: none; cursor: pointer; }
#page-airules .ur-del { width: 28px; height: 28px; border-radius: 6px; border: 1px solid var(--risk-high); background: var(--risk-high-bg); color: var(--risk-high); cursor: pointer; font-size: .8rem; font-weight: 700; }
#page-airules .ur-del:hover { background: var(--risk-high); color: #fff; }
#page-airules .sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
#page-airules .ur-tools, #page-airules .ur-decide, #page-airules .ur-tell, #page-airules .ur-groups { table-layout: fixed; }
#page-airules .ur-tools th:nth-child(1) { width: 24%; }
#page-airules .ur-tools th:nth-child(2) { width: 20%; }
#page-airules .ur-tools th:nth-child(4) { width: 56px; }
#page-airules .ur-tools td:first-child { padding-right: 16px; }
#page-airules .ur-tools td:first-child b { display: inline-block; background: var(--eu-blue); color: #fff; border-radius: 8px; padding: 5px 12px; font-size: .86rem; }
#page-airules .aur-pick { display: flex; gap: 8px; align-items: center; margin-top: 12px; flex-wrap: wrap; }
#page-airules .aur-pick .input { flex: 1; min-width: 260px; max-width: 560px; }

/* bubbles (approved features, what to check) */
#page-airules .ur-feat .chips { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; border: 1px solid var(--grey-300); border-radius: 6px; background: #fff; padding: 4px 6px; min-height: 34px; cursor: text; }
#page-airules .ur-feat .chip { display: inline-flex; align-items: center; gap: 4px; background: #EEF3FF; color: #1E3A8A; border: 1px solid #C7D7FE; border-radius: 999px; padding: 2px 4px 2px 10px; font-size: .8rem; max-width: 100%; overflow-wrap: anywhere; }
#page-airules .ur-feat .chip button { border: 0; background: none; color: inherit; cursor: pointer; font-size: .8rem; line-height: 1; padding: 2px 5px; border-radius: 999px; }
#page-airules .ur-feat .chip button:hover { background: rgba(30,58,138,.12); }
#page-airules .ur-feat input { border: 0; outline: 0; flex: 1; min-width: 140px; font: inherit; font-size: .82rem; padding: 3px 2px; background: none; }

/* section 3 */
#page-airules .ur-groups { font-size: .98rem; }
#page-airules .ur-groups thead th { font-size: .78rem; white-space: nowrap; }
#page-airules .ur-groups tbody td { padding: 13px 8px; }
#page-airules .ur-groups tbody tr:nth-child(even) td { background: var(--grey-50); }
#page-airules .ur-groups input[type=checkbox] { width: 22px; height: 22px; cursor: pointer; accent-color: var(--risk-high); }
#page-airules .ur-must td.c { padding-top: 18px; }
#page-airules .ur-must select, #page-airules .ur-must .own { width: 100%; max-width: 560px; font: inherit; font-size: .92rem; padding: 6px 8px; border: 1px solid var(--grey-300); border-radius: 6px; background: #fff; box-sizing: border-box; }
#page-airules .ur-must .own { margin-top: 6px; display: block; }
#page-airules select.ur-empty { color: var(--grey-500); }
#page-airules select option { color: var(--grey-900); }

/* section 5 */
#page-airules .ur-tell select, #page-airules .ur-tell .own { width: 100%; max-width: none; box-sizing: border-box; font-size: .86rem; padding: 6px 8px; }
#page-airules .ur-tell .own { margin-top: 6px; display: block; border: 1px solid var(--grey-300); border-radius: 6px; }
#page-airules .ur-who details { position: relative; }
#page-airules .ur-who summary { list-style: none; cursor: pointer; font-size: .86rem; padding: 6px 26px 6px 8px; border: 1px solid var(--grey-300); border-radius: 6px; background: #fff; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; position: relative; }
#page-airules .ur-who summary.ur-empty { color: var(--grey-500); }
#page-airules .ur-who summary::-webkit-details-marker { display: none; }
#page-airules .ur-who summary::after { content: "▾"; position: absolute; right: 9px; top: 6px; color: var(--grey-500); }
#page-airules .ur-who .box { position: absolute; z-index: 20; top: calc(100% + 4px); left: 0; background: #fff; border: 1px solid var(--grey-200); border-radius: 8px; box-shadow: 0 6px 18px rgba(11,27,63,.12); padding: 8px 10px; display: grid; gap: 5px; min-width: 240px; }
#page-airules .ur-who .box label { display: flex; gap: 8px; align-items: center; font-size: .84rem; color: var(--grey-800); white-space: nowrap; cursor: pointer; }
#page-airules .ur-who .box .input { font-size: .82rem; padding: 4px 6px; margin-top: 4px; }

#page-airules .ur-foot { display: flex; justify-content: flex-end; gap: 10px; margin: 6px 0 30px; }

/* view-only (example, or a draft with no live pass) */
#page-airules .ur-readonly .ur-del, #page-airules .ur-readonly .ur-add, #page-airules .ur-readonly .chip button,
#page-airules .ur-readonly .aur-pick, #page-airules .ur-readonly .chips input { display: none; }
#page-airules .ur-readonly #aurViewForm input, #page-airules .ur-readonly #aurViewForm select,
#page-airules .ur-readonly #aurViewForm textarea, #page-airules .ur-readonly #aurViewForm summary { pointer-events: none; }

/* the document (Preview) — a business policy document (user, 2026-10-14) */
#page-airules .ur-doc { background: #fff; border: 1px solid var(--grey-200); border-radius: 12px; padding: 30px 34px; box-shadow: 0 2px 10px rgba(11,27,63,.05); }
#page-airules .ur-doc h1 { font-family: var(--display); font-size: 1.5rem; color: var(--grey-900); margin: 0 0 4px; }
#page-airules .ur-doc p, #page-airules .ur-doc li { font-size: .9rem; color: var(--grey-800); line-height: 1.55; }
#page-airules .pd-draftmark { border: 2px dashed var(--grey-400); color: var(--grey-500); font-weight: 700; letter-spacing: .1em; text-align: center; padding: 8px; margin-bottom: 16px; border-radius: 6px; }
#page-airules .pd-kicker { font-size: .72rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--eu-blue); margin-bottom: 2px; }
#page-airules .pd-ctl { width: 100%; border-collapse: collapse; margin: 12px 0 20px; font-size: .82rem; }
#page-airules .pd-ctl th { text-align: left; width: 150px; color: var(--grey-500); font-weight: 600; padding: 5px 10px; background: var(--grey-50); border: 1px solid var(--grey-200); }
#page-airules .pd-ctl td { padding: 5px 10px; border: 1px solid var(--grey-200); color: var(--grey-900); }
#page-airules .ur-doc h4.pd-h { font-family: var(--display); font-size: .98rem; color: var(--grey-900); border-bottom: 2px solid var(--eu-blue); padding-bottom: 4px; margin: 24px 0 6px; }
#page-airules .pd-h .pd-n { color: var(--eu-blue); margin-right: 6px; }
#page-airules .pd-table { width: 100%; border-collapse: collapse; margin: 8px 0; font-size: .86rem; }
#page-airules .pd-table th { text-align: left; font-size: .7rem; letter-spacing: .05em; text-transform: uppercase; color: var(--grey-500); padding: 7px 10px; background: var(--grey-50); border: 1px solid var(--grey-200); }
#page-airules .pd-table td { padding: 7px 10px; border: 1px solid var(--grey-200); color: var(--grey-800); vertical-align: top; }
#page-airules .pd-table td.c, #page-airules .pd-table th.c { text-align: center; }
#page-airules .pd-no { color: #B42318; font-weight: 700; }
#page-airules .pd-dash { color: var(--grey-400); }
#page-airules .ur-doc ol.pd-q { padding-left: 22px; margin: 6px 0; }
#page-airules .ur-doc ol.pd-q li { margin: 3px 0; }
#page-airules .ur-small { font-size: .76rem !important; color: var(--grey-500) !important; margin-top: 22px; }

/* paper: the document only; short sections kept whole; footer comes from #aurPageStyle (airules.js) */
@media print {
  #page-airules .ur-head, #page-airules .ra-back-btn, #page-airules .ur-docline, #page-airules .ur-ex-note,
  #page-airules .ur-tabs, #page-airules .ur-foot, #page-airules .ur-release, #page-airules #aurViewForm { display: none !important; }
  #page-airules .ur-doc { border: 0 !important; box-shadow: none !important; padding: 0 !important; border-radius: 0; }
  #page-airules .pd-table tr { page-break-inside: avoid; }
  #page-airules h4.pd-h { page-break-after: avoid; break-after: avoid; }
  #page-airules .pd-sec.pd-keep { page-break-inside: avoid; break-inside: avoid; }
  #page-airules ol.pd-q { page-break-inside: avoid; break-inside: avoid; }
  #page-airules .pd-table th, #page-airules .pd-ctl th { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}

/* ═══ DASHBOARD HOME · TWO ROWS (user, 2026-10-14; local/dashboard-home-two-rows-mockup.html) ═══
   "Manage your business's AI use" (Software Library → AI Use Rules, then AI literacy) and the
   EU AI Act workflow. renderHomeTiles() decides which row comes first. */
.dash-home-row { margin-bottom: 8px; }
.dash-flow-sub { margin: -6px 0 14px; font-size: .84rem; color: var(--grey-600); }
/* a short description under every tile title */
.dash-card-desc { display: block; font-size: .8rem; color: var(--grey-600); line-height: 1.4; margin: -4px 0 6px; text-align: center; }
/* the AI-use row: card → arrow → card, a gap, card. A grid, so the "See example" pill is exactly as wide as its card. */
.dash-use-flow, .dash-use-eg { display: grid; grid-template-columns: minmax(0, 1fr) 22px minmax(0, 1fr) 36px minmax(0, 1fr); column-gap: 4px; align-items: stretch; }
.dash-use-flow .dash-flow-arrow { align-self: center; }
.dash-use-eg .dash-eg-slot { margin: 0; }
/* own colours (the workflow's nth-of-type colours would otherwise apply) */
.dash-flow-step.dash-use-lib   { --accent: #3b5bdb; --accent-2: #5c7cfa; }
.dash-flow-step.dash-use-rules { --accent: #c2255c; --accent-2: #f06595; }
.dash-flow-step.dash-use-lit   { --accent: #0b7285; --accent-2: #15aabf; }
.dash-new-pill { display: inline-block; margin-left: 4px; font-size: .62rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  background: #0b7285; color: #fff; border-radius: 99px; padding: 1px 7px; vertical-align: 1px; }
@media (max-width: 720px) {
  .dash-use-flow, .dash-use-eg { display: flex; flex-direction: column; }
  .dash-use-sep { display: none; }
  .dash-use-flow .dash-flow-step { grid-template-areas: "icon label" "icon desc" "icon stats"; }
  .dash-flow-step { grid-template-areas: "icon label" "icon desc" "icon stats"; }
  .dash-card-desc { grid-area: desc; text-align: left; margin: 0; }
}

/* Sidebar: the EU AI Act pages grouped under one label (user, 2026-10-14). */
.dash-nav-group { display: flex; flex-direction: column; gap: 2px; margin: 8px 0; padding: 6px 4px 6px; border: 1px solid var(--grey-400); border-radius: 10px; background: var(--grey-50); }   /* darker edge (user, 2026-10-14) */
.dash-nav-group-label { align-self: flex-start; margin: 2px 6px 4px; font-size: .68rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: #fff; background: var(--eu-blue); border-radius: 999px; padding: 3px 10px; }   /* white on a blue pill (user, 2026-10-14) */
@media (max-width: 720px) { .dash-nav-group { display: contents; } .dash-nav-group-label { display: none; } }

/* Pass card: what the pass includes, in groups (user, 2026-10-14) — EU AI Act path / Manage your business's AI use / For both. */
.pass-list li.pass-group { padding: 12px 0 2px; font-size: .68rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--grey-500); border-bottom: 1px solid var(--grey-200); margin-bottom: 2px; }
.pass-list li.pass-group:first-child { padding-top: 0; }
/* A divider between the two home rows, whichever comes first (user, 2026-10-14). */
#homeRows > .dash-home-row + .dash-home-row { border-top: 2px solid var(--grey-400); padding-top: 24px; margin-top: 10px; }   /* stronger (user: "can barely see it") */
/* …and the same line between the rows and the pass card below them (user, 2026-10-14). */
#homeRows { border-bottom: 2px solid var(--grey-400); padding-bottom: 6px; margin-bottom: 24px; }
