/* Nextstep4u — the signed-in dashboard.
 *
 * A page of its own, not the old left-rail app shell. The rail was a desktop
 * idea: it spent 260px on a list of five links for an audience that opens this
 * on a 360px phone, and it pushed the one thing a candidate came to read —
 * where do I stand — below the fold on anything smaller than a laptop.
 *
 * This sits on top of app.css, which owns the tokens, the reset, the type
 * scale and the motion layer. Nothing here invents a colour: every value is a
 * token or an approved canvas colour, because scripts/check-palette.py says so
 * and it is right to.
 *
 * Class names are prefixed `dash-`. The homepage's `v1-` rules and the older
 * app rules both load on some pages; a prefix is cheaper than finding out
 * which rule won.
 *
 * Motion is transform and opacity only, 120-420ms, and the whole layer
 * collapses under prefers-reduced-motion. The audience is on a mid-range
 * Android over a congested 4G cell, and a dashboard that janks on arrival
 * reads as a slow product no matter what the numbers on it say.
 */

/* ── skip link ──────────────────────────────────────────────────────────
   Off-screen until focused, then a real, visible target. Defined here as well
   as in v1.css because app.css has never carried it, and a page that loads
   neither stylesheet shows the link sitting in plain view at the top. */
.skip{
  position:absolute; left:-9999px; top:0; z-index:100;
  background:var(--page); color:var(--ink);
  border:1px solid var(--line-3); border-radius:var(--r-sm);
  padding:12px 18px; font-weight:600;
}
.skip:focus{ left:12px; top:12px; }

/* ── shell ──────────────────────────────────────────────────────────────── */

.dash-body{ background:var(--shell); }

/* The hidden attribute has to beat a class that sets display, or a card
   switched off in markup still draws its borders and its gap. */
[hidden]{ display:none !important; }

/* ── the welcome band ───────────────────────────────────────────────────
   Inverted on purpose. It is the one block on the page that is about the
   person rather than about a number, so putting it on navy separates it from
   the cards below instead of making it the first of them. The same surface
   carries the quote on the sign-in page, so arriving here straight after
   signing in reads as continuing rather than as landing somewhere else. */

.dash-hero{
  position:relative; overflow:hidden;
  border-radius:var(--r-xl); color:#fff;
  background:
    radial-gradient(90% 70% at 92% 6%, rgba(var(--amber-rgb),.085), rgba(0,0,0,0) 60%),
    radial-gradient(70% 90% at 4% 96%, rgba(2,101,224,.26), rgba(0,0,0,0) 62%),
    linear-gradient(140deg, #171F2C 0%, #0D1420 58%, #1B2431 100%);
  padding:30px 34px; display:flex; align-items:center; gap:30px; flex-wrap:wrap;
  box-shadow:var(--shadow-2);
}
@media (max-width:640px){ .dash-hero{ padding:24px 20px; gap:22px; border-radius:var(--r-lg); } }

/* A slow sweep of light across the panel. Decorative, behind everything, and
   the first thing reduced motion switches off. */
.dash-hero-sweep{
  position:absolute; top:0; bottom:0; left:0; width:30%; pointer-events:none;
  background:linear-gradient(100deg, transparent, rgba(255,255,255,.055), transparent);
  animation:dashSweep 9s ease-in-out infinite;
}
@keyframes dashSweep{ 0%{ transform:translateX(-140%); } 60%,100%{ transform:translateX(480%); } }

.dash-hero-in{ position:relative; flex:1; min-width:258px; }

.dash-eyebrow{
  font-size:.7rem; font-weight:700; letter-spacing:.14em; text-transform:uppercase;
  color:var(--amber); margin-bottom:10px;
}
.dash-greet{
  font-size:clamp(1.5rem,3.2vw,2.05rem); font-weight:700; letter-spacing:-.025em;
  line-height:1.15; margin-bottom:10px;
}
.dash-greet-name{ color:var(--amber); }
.dash-hero-line{ font-size:.94rem; line-height:1.6; color:#E6E9ED; max-width:46em; }
.dash-hero-acts{ display:flex; gap:10px; flex-wrap:wrap; margin-top:20px; }

/* Buttons on the dark panel. The outline one carries a label on navy, so it
   is a white hairline rather than the page's grey border, which disappears
   against it entirely. */
.dash-btn{
  display:inline-flex; align-items:center; justify-content:center; gap:7px;
  padding:11px 19px; border-radius:var(--r-md); border:1px solid transparent;
  font-size:.875rem; font-weight:600; text-decoration:none; cursor:pointer;
  transition:transform .16s var(--ease), background .18s var(--ease), box-shadow .18s var(--ease);
}
.dash-btn:active{ transform:translateY(1px); }
.dash-btn-amber{ background:var(--amber); color:var(--night); box-shadow:0 6px 18px rgba(var(--amber-rgb),.3); }
.dash-btn-amber:hover{ background:#FBE49B; }
.dash-btn-wire{ border-color:rgba(255,255,255,.26); color:#fff; }
.dash-btn-wire:hover{ background:rgba(255,255,255,.08); border-color:rgba(255,255,255,.45); }

/* ── the days-left ring ─────────────────────────────────────────────────
   A pass nobody is counting down is a renewal that does not happen: the day
   it ends is the first day the candidate thinks about it, and by then they
   have gone somewhere else.

   It is drawn from a real expiry date or it is not drawn at all. There is no
   "assume ninety days" here — the fraction would be invented, and this is the
   one number on the page somebody might actually act on. */

.dash-ring{ position:relative; flex:none; width:132px; height:132px; display:grid; place-items:center; }
.dash-ring-track{
  position:absolute; inset:0; border-radius:50%;
  background:conic-gradient(var(--amber) calc(var(--pc,0) * 1%), rgba(255,255,255,.12) 0);
}
.dash-ring-hole{
  position:absolute; inset:9px; border-radius:50%;
  background:linear-gradient(140deg, #171F2C, #0D1420);
}
.dash-ring-in{ position:relative; text-align:center; line-height:1; }
.dash-ring-n{ font-size:2.1rem; font-weight:700; letter-spacing:-.03em; font-variant-numeric:tabular-nums; }
.dash-ring-l{
  font-size:.66rem; font-weight:700; letter-spacing:.12em; text-transform:uppercase;
  color:#94A0AE; margin-top:7px;
}
/* On a phone the ring drops below the buttons, and a 112px circle pinned to
   the left edge of a full-width panel reads as something that failed to load
   beside it. Centred, it reads as the panel's footer. */
@media (max-width:640px){
  .dash-ring{ width:112px; height:112px; margin:0 auto; }
  .dash-ring-n{ font-size:1.75rem; }
}

/* A status word beside the greeting, coloured by what it says. */
.dash-chip{
  display:inline-flex; align-items:center; gap:6px;
  padding:5px 11px; border-radius:999px; vertical-align:middle;
  font-size:.72rem; font-weight:700; letter-spacing:.05em; text-transform:uppercase;
  background:rgba(255,255,255,.1); color:#fff; border:1px solid rgba(255,255,255,.16);
}
.dash-chip-live{ background:rgba(0,182,150,.18); border-color:rgba(0,182,150,.4); color:#A8E5D9; }
.dash-chip-warn{ background:rgba(var(--amber-rgb),.16); border-color:rgba(var(--amber-rgb),.42); color:#FBE49B; }
.dash-chip-off{ background:rgba(217,56,67,.2); border-color:rgba(217,56,67,.46); color:#FDECED; }
.dash-chip-dot{ width:5px; height:5px; border-radius:50%; background:currentColor; animation:dashPulse 1.6s ease-in-out infinite; }
@keyframes dashPulse{ 0%,100%{ opacity:1; } 50%{ opacity:.3; } }

/* ── the preview marker ─────────────────────────────────────────────────
   Only drawn when the page was opened with ?preview=. It is loud on purpose:
   a screenshot of sample data must never be mistakable for a screenshot of
   somebody's real account. */
.dash-preview{
  display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  border-radius:var(--r-lg); padding:12px 16px; margin-bottom:16px;
  background:var(--amber-bg); border:1px solid var(--amber-line);
  font-size:.86rem; line-height:1.5; color:var(--amber-deep);
}
.dash-preview b{
  flex:none; background:var(--amber); color:var(--night);
  font-size:.68rem; font-weight:700; letter-spacing:.12em; text-transform:uppercase;
  padding:4px 9px; border-radius:5px;
}
.dash-preview a{ color:var(--amber-deep); font-weight:600; }

/* ── notices ────────────────────────────────────────────────────────────
   A read that failed is said once, in words, at the top. Four half-drawn
   panels is how a working page gets reported as broken. */

.dash-note{
  border-radius:var(--r-lg); padding:15px 18px; margin-bottom:16px;
  font-size:.9rem; line-height:1.6;
  background:var(--page); border:1px solid var(--line); color:var(--ink-2);
}
.dash-note b{ color:var(--ink); display:block; margin-bottom:3px; }
.dash-note a{ color:var(--blue); font-weight:600; }
.dash-note-bad{ background:var(--red-bg); border-color:#FDECED; }
.dash-note-bad b{ color:var(--red); }

/* ── arrival ────────────────────────────────────────────────────────────
   Each block comes up once, staggered by --d, after the page has painted.
   Nothing moves on scroll here: a dashboard is read, not toured, and a card
   that animates every time it passes the fold is noise. */

.dash-rise{ opacity:0; transform:translateY(14px); }
.dash-ready .dash-rise{ animation:dashRise .5s var(--ease) forwards; animation-delay:var(--d,0ms); }
@keyframes dashRise{ to{ opacity:1; transform:none; } }

@media (prefers-reduced-motion:reduce){
  .dash-hero-sweep,.dash-chip-dot{ animation:none; }
  .dash-rise{ opacity:1; transform:none; }
  .dash-ready .dash-rise{ animation:none; }
  .dash-bar i,.dash-card,.dash-card-go svg{ transition:none; }
}

/* ── the four journeys ──────────────────────────────────────────────────
   Straight from the owner flow diagram: a dashboard opens onto Test and
   practice, the Learning book, the Study plan, and the Batch that paid for
   them. Everything else on this page is detail hanging off one of the four.

   They are cards rather than rail links because the rail is chrome and this
   is the point of the screen. On a phone the rail is not even there.

   Each one carries a real figure or an honest sentence saying there is not
   one yet. None of them is ever blank: a card that renders nothing is
   indistinguishable from a card that failed. */

.dash-h2{
  font-size:.72rem; font-weight:700; letter-spacing:.12em; text-transform:uppercase;
  color:var(--ink-4); margin:30px 0 14px;
}

.dash-grid4{ display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:16px; }
@media (max-width:1240px){ .dash-grid4{ grid-template-columns:repeat(2,minmax(0,1fr)); } }
@media (max-width:620px){ .dash-grid4{ grid-template-columns:1fr; } }

.dash-card{
  position:relative; overflow:hidden;
  display:flex; flex-direction:column;
  background:var(--page); border:1px solid var(--line); border-radius:var(--r-lg);
  padding:20px; text-decoration:none; color:inherit;
  transition:transform .18s var(--ease), box-shadow .18s var(--ease), border-color .18s var(--ease);
}
a.dash-card:hover{ transform:translateY(-3px); box-shadow:var(--shadow-2); border-color:var(--line-3); }

/* A wash of the card accent in the top corner. Decorative, behind the text,
   and the reason four white rectangles read as four different things. */
.dash-card::before{
  content:""; position:absolute; top:-40%; right:-30%; width:70%; height:120%;
  background:radial-gradient(closest-side, var(--wash, transparent), rgba(0,0,0,0));
  pointer-events:none;
}
.dash-card > *{ position:relative; }

.dash-card-ic{
  width:42px; height:42px; border-radius:11px; flex:none;
  display:grid; place-items:center; margin-bottom:14px;
  background:var(--ic-bg, var(--chip)); color:var(--ic-fg, var(--ink-2));
}
.dash-card-t{ font-size:1.02rem; font-weight:700; letter-spacing:-.01em; line-height:1.25; }
.dash-card-p{ font-size:.84rem; line-height:1.55; color:var(--ink-3); margin-top:10px; }

/* The figure, when there is one. It counts up from zero on arrival, which is
   the one place on this page where a number moving is worth the frames. */
.dash-card-n{
  display:flex; align-items:baseline; gap:7px; margin-top:14px;
  font-variant-numeric:tabular-nums;
}
.dash-card-n b{ font-size:1.7rem; font-weight:700; letter-spacing:-.03em; line-height:1; color:var(--ink); }
.dash-card-n span{ font-size:.78rem; font-weight:600; color:var(--ink-3); }

.dash-card-go{
  margin-top:auto; padding-top:16px;
  display:flex; align-items:center; gap:6px;
  font-size:.82rem; font-weight:700; color:var(--go, var(--blue));
}
.dash-card-go svg{ transition:transform .18s var(--ease); }
a.dash-card:hover .dash-card-go svg{ transform:translateX(3px); }

/* Bottom-aligned, the same as the link on a card that has one, so the four
   cards read as a row rather than as four things of different heights. */
/* The transparent top border is the 16px of air the link on a sibling card
   gets from its padding. Clipped to the padding box so the chip background
   does not paint under it. */
.dash-card-soon{
  align-self:flex-start; margin-top:auto;
  border-top:16px solid transparent; background-clip:padding-box;
  font-size:.69rem; font-weight:800; padding:3px 9px; border-radius:999px;
  background:var(--chip); color:var(--ink-3);
}

/* ── resume ─────────────────────────────────────────────────────────────
   An abandoned attempt is the single biggest reason a candidate never comes
   back, so when one is running it takes the width of the page and sits above
   the four. When nothing is running it is not drawn at all — the four cards
   already say what to do next, and an empty strip here would only push them
   down. */

.dash-resume{
  display:flex; align-items:center; gap:22px; flex-wrap:wrap;
  background:var(--blue-tint); border:1px solid var(--blue-line);
  border-radius:var(--r-lg); padding:18px 22px; margin-top:16px;
  text-decoration:none; color:inherit;
  transition:box-shadow .18s var(--ease);
}
.dash-resume:hover{ box-shadow:var(--shadow-2); }
.dash-resume-in{ flex:1; min-width:230px; }
.dash-resume-k{
  font-size:.69rem; font-weight:700; letter-spacing:.12em; text-transform:uppercase;
  color:var(--blue); margin-bottom:6px; display:flex; align-items:center; gap:7px;
}
.dash-resume-t{ font-size:1.05rem; font-weight:700; letter-spacing:-.01em; }
.dash-resume-s{ font-size:.84rem; color:var(--ink-3); margin-top:5px; }
.dash-bar{ height:7px; border-radius:99px; background:var(--blue-line); overflow:hidden; margin-top:12px; }
.dash-bar i{ display:block; height:100%; border-radius:99px; background:var(--blue); width:0; transition:width .9s var(--ease); }
.dash-resume-btn{
  flex:none; display:inline-flex; align-items:center; gap:7px;
  padding:12px 20px; border-radius:var(--r-md);
  background:var(--blue); color:#fff; font-size:.875rem; font-weight:700;
  box-shadow:var(--shadow-3);
}

/* ── a page heading ─────────────────────────────────────────────────────
   Every screen inside the shell opens with the same three lines: what this
   is, what it is for, and a count where there is one to give. The old shell
   put the title in the top bar, which meant it scrolled away and competed
   with the brand for the same strip of pixels. */

.dash-head{ display:flex; align-items:flex-end; gap:18px; flex-wrap:wrap; margin-bottom:20px; }
.dash-head-in{ flex:1; min-width:240px; }
.dash-h1{ font-size:1.55rem; font-weight:700; letter-spacing:-.025em; line-height:1.2; }
.dash-lede{ font-size:.9rem; line-height:1.6; color:var(--ink-3); margin-top:7px; max-width:58ch; }

/* ── filter chips ───────────────────────────────────────────────────────
   Each carries its own count, and a chip whose count is zero is not drawn.
   The counts are computed from the rows that exist; the version before this
   had them written into the markup, on the one screen whose whole job is to
   say what you actually have. */

.dash-chips{ display:flex; gap:8px; flex-wrap:wrap; margin-bottom:18px; }
.dash-chip-btn{
  display:inline-flex; align-items:center; gap:7px;
  padding:8px 14px; border-radius:999px; cursor:pointer;
  border:1px solid var(--line); background:var(--page);
  font:inherit; font-size:.84rem; font-weight:600; color:var(--ink-2);
  transition:background .16s var(--ease), border-color .16s var(--ease), color .16s var(--ease);
}
.dash-chip-btn:hover{ background:var(--chip); }
.dash-chip-btn[aria-pressed="true"]{ background:var(--blue); border-color:var(--blue); color:#fff; }
.dash-chip-n{
  font-size:.75rem; font-weight:700; font-variant-numeric:tabular-nums;
  padding:1px 7px; border-radius:999px; background:var(--chip); color:var(--ink-3);
}
.dash-chip-btn[aria-pressed="true"] .dash-chip-n{ background:rgba(255,255,255,.22); color:#fff; }

/* ── a paper ────────────────────────────────────────────────────────────
   One row per paper. The stripe down the left is the state, so a library of
   twenty is scannable without reading a single badge. Nothing is hidden when
   it is locked: a paper that disappears from the library reads as data lost,
   so a locked row says what happened and what reopens it. */

.dash-list{ display:flex; flex-direction:column; gap:12px; }

.dash-paper{
  position:relative; overflow:hidden;
  display:flex; align-items:center; gap:18px; flex-wrap:wrap;
  background:var(--page); border:1px solid var(--line); border-radius:var(--r-lg);
  padding:18px 20px 18px 23px;
  transition:transform .18s var(--ease), box-shadow .18s var(--ease), border-color .18s var(--ease);
}
.dash-paper::before{
  content:""; position:absolute; left:0; top:0; bottom:0; width:4px;
  background:var(--stripe, var(--line-3));
}
.dash-paper-live:hover{ transform:translateY(-2px); box-shadow:var(--shadow-2); border-color:var(--line-3); }

.dash-paper-ic{
  width:44px; height:44px; border-radius:12px; flex:none;
  display:grid; place-items:center;
  background:var(--ic-bg, var(--chip)); color:var(--ic-fg, var(--ink-3));
}
.dash-paper-in{ flex:1; min-width:210px; }
.dash-paper-top{ display:flex; align-items:center; gap:9px; flex-wrap:wrap; margin-bottom:5px; }
.dash-paper-t{ font-size:1rem; font-weight:700; letter-spacing:-.01em; }
.dash-paper-m{ font-size:.83rem; color:var(--ink-3); line-height:1.5; }
.dash-paper-note{ font-size:.81rem; font-weight:600; color:var(--note, var(--ink-3)); margin-top:4px; }

.dash-tag{
  font-size:.68rem; font-weight:800; letter-spacing:.06em; text-transform:uppercase;
  padding:3px 9px; border-radius:999px;
  background:var(--chip); color:var(--ink-3);
}
.dash-tag-open{ background:var(--blue-bg); color:var(--blue-deep); }
.dash-tag-free{ background:var(--green-bg); color:var(--green-deep); }
.dash-tag-run{ background:var(--amber-bg); color:#8A6200; }
.dash-tag-off{ background:var(--red-bg); color:var(--red); }

.dash-go{
  flex:none; display:inline-flex; align-items:center; gap:7px;
  padding:11px 19px; border-radius:var(--r-md); text-decoration:none;
  font-size:.86rem; font-weight:700; border:1px solid transparent;
  transition:transform .16s var(--ease), background .16s var(--ease);
}
.dash-go:active{ transform:translateY(1px); }
.dash-go-primary{ background:var(--blue); color:#fff; box-shadow:var(--shadow-3); }
.dash-go-primary:hover{ background:var(--blue-deep); }
.dash-go-amber{ background:var(--amber); color:var(--night); box-shadow:0 6px 18px rgba(var(--amber-rgb),.3); }
.dash-go-amber:hover{ background:#FBE49B; }
.dash-go-wire{ border-color:var(--line-3); color:var(--ink-2); background:var(--page); }
.dash-go-wire:hover{ background:var(--chip); }
.dash-go-flat{ color:var(--ink-4); font-weight:600; font-size:.8rem; padding:11px 0; }

/* ── an empty library ───────────────────────────────────────────────────
   Dashed rather than solid, so it reads as a space waiting to be filled
   rather than as a card that failed to load. */
.dash-empty{
  border:1.5px dashed var(--line-3); border-radius:var(--r-lg);
  background:var(--page); text-align:center; padding:46px 26px;
}
.dash-empty b{ display:block; font-size:1.06rem; font-weight:700; margin-bottom:7px; }
.dash-empty p{ font-size:.89rem; line-height:1.6; color:var(--ink-3); max-width:46ch; margin:0 auto 20px; }

/* ── a standing note ────────────────────────────────────────────────── */
.dash-tip{
  display:flex; gap:13px; align-items:flex-start;
  background:var(--blue-tint); border:1px solid var(--blue-line);
  border-radius:var(--r-lg); padding:16px 19px; margin-top:22px;
}
.dash-tip svg{ flex:none; color:var(--blue); margin-top:1px; }
.dash-tip b{ display:block; font-size:.9rem; margin-bottom:3px; }
.dash-tip p{ font-size:.85rem; line-height:1.6; color:var(--ink-2); margin:0; }

/* ═══════════════════════════════════════════════════════════════════════════
   WHERE TO SPEND YOUR STUDY TIME
   ═══════════════════════════════════════════════════════════════════════════

   The band that makes this a coaching product rather than a marks sheet.

   It sits directly under the resume strip because it is the reason to come
   back between tests: a score tells somebody how they did, and this tells
   them what to do on Tuesday evening.

   It is NEVER blank. Every state it can be in -- no mock sat yet, questions
   not tagged, too little evidence to be honest -- has its own sentence and
   its own next action, because an empty panel reads as a broken site and
   sends nobody anywhere. */

.dash-focus{
  position:relative; overflow:hidden;
  background:var(--page); border:1px solid var(--line); border-radius:var(--r-lg);
  padding:26px 28px; margin-top:28px; box-shadow:var(--shadow-1);
}
@media (max-width:640px){ .dash-focus{ padding:22px 18px; } }

/* A quiet wash that leans the panel towards "diagnosis" rather than "report".
   Decorative only; nothing is read from it. */
.dash-focus::before{
  content:''; position:absolute; inset:0 auto auto 0; width:340px; height:340px;
  background:radial-gradient(closest-side,rgba(2,101,224,.07),transparent);
  transform:translate(-36%,-52%); pointer-events:none;
}
.dash-focus > *{ position:relative; }

.dash-focus-head{ display:flex; align-items:flex-end; gap:16px; flex-wrap:wrap; }
.dash-focus-head .dash-h2{ margin:0; }
.dash-focus-why{
  font-size:.82rem; color:var(--ink-3); line-height:1.5; margin-top:6px; max-width:54ch;
}
.dash-focus-link{
  margin-left:auto; font-size:.84rem; font-weight:650; color:var(--blue);
  display:inline-flex; align-items:center; gap:5px; white-space:nowrap;
}
.dash-focus-link svg{ transition:transform .18s var(--ease); }
.dash-focus-link:hover svg{ transform:translateX(3px); }

/* ── the three numbers ──────────────────────────────────────────────────
   Questions sat, the candidate's own pace, and the time that went into
   answers that turned out wrong. The third is the one that changes behaviour:
   it is the cost of not moving on. */
.dash-stats{
  display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:1px;
  background:var(--line-2); border:1px solid var(--line); border-radius:var(--r-md);
  overflow:hidden; margin-top:20px;
}
@media (max-width:560px){ .dash-stats{ grid-template-columns:1fr; } }
.dash-stat{ background:var(--page); padding:15px 17px; }
.dash-stat-n{
  font-size:1.5rem; font-weight:700; letter-spacing:-.03em; line-height:1.1;
  color:var(--ink); font-variant-numeric:tabular-nums;
}
.dash-stat-n small{ font-size:.82rem; font-weight:600; color:var(--ink-3); letter-spacing:0; }
.dash-stat-l{ font-size:.76rem; font-weight:600; color:var(--ink-3); margin-top:5px; line-height:1.4; }

/* ── one topic to work on ───────────────────────────────────────────────
   The colour carries the ACTION, not the score. Amber is "you know this,
   it is costing you time"; red is "go back to the concept"; blue is
   "practise"; green is "leave it alone". A candidate learns the three
   colours once and then reads the panel at a glance. */
.dash-focus-list{ display:flex; flex-direction:column; gap:12px; margin-top:18px; }

.dash-topic{
  position:relative; display:flex; gap:15px; align-items:flex-start;
  border:1px solid var(--line); border-left:4px solid var(--tone,var(--line-3));
  border-radius:var(--r-md); padding:15px 17px; background:var(--page);
  transition:border-color .18s var(--ease), box-shadow .18s var(--ease), transform .18s var(--ease);
}
.dash-topic:hover{ box-shadow:var(--shadow-2); transform:translateY(-1px); }

/* On a phone the chip beside the headline squeezes it into a two-word column.
   Stacked instead: the action chip reads first, then the sentence it labels. */
@media (max-width:560px){
  .dash-topic{ flex-direction:column-reverse; align-items:flex-start; gap:10px; }
}

.dash-topic-in{ flex:1; min-width:0; }
.dash-topic-t{ font-size:.96rem; font-weight:700; letter-spacing:-.01em; line-height:1.3; color:var(--ink); }
.dash-topic-p{ font-size:.84rem; line-height:1.6; color:var(--ink-3); margin-top:6px; }

.dash-topic-k{
  display:inline-flex; align-items:center; gap:6px; flex:none;
  font-size:.68rem; font-weight:800; letter-spacing:.07em; text-transform:uppercase;
  padding:5px 10px; border-radius:99px;
  background:var(--tone-bg,var(--chip)); color:var(--tone-ink,var(--ink-3));
}

/* The evidence, in the smallest type on the panel. It is there so a candidate
   who asks "why are you telling me this" has an answer on the same line. */
.dash-topic-ev{
  display:flex; gap:14px; flex-wrap:wrap; margin-top:10px;
  font-size:.76rem; color:var(--ink-3); font-variant-numeric:tabular-nums;
}
.dash-topic-ev b{ color:var(--ink-2); font-weight:700; }

/* Accuracy, drawn. Width is the real figure and nothing else. */
.dash-topic-bar{
  height:5px; border-radius:99px; background:var(--line-2);
  overflow:hidden; margin-top:11px;
}
.dash-topic-bar i{
  display:block; height:100%; border-radius:99px; width:0;
  background:var(--tone,var(--blue)); transition:width .85s var(--ease);
}

.dash-tone-weak    { --tone:var(--red);        --tone-bg:var(--red-bg);   --tone-ink:var(--red); }
.dash-tone-guessing{ --tone:var(--red);        --tone-bg:var(--red-bg);   --tone-ink:var(--red); }
.dash-tone-avoided { --tone:var(--ink-4);      --tone-bg:var(--chip);     --tone-ink:var(--ink-2); }
.dash-tone-slow    { --tone:var(--amber);      --tone-bg:var(--amber-bg); --tone-ink:var(--amber-deep); }
.dash-tone-shaky   { --tone:var(--blue);       --tone-bg:var(--blue-bg);  --tone-ink:var(--blue-deep); }
.dash-tone-strong  { --tone:var(--green);      --tone-bg:var(--green-bg); --tone-ink:var(--green-deep); }
.dash-tone-thin    { --tone:var(--line-3);     --tone-bg:var(--chip);     --tone-ink:var(--ink-3); }

/* ── nothing to say yet ─────────────────────────────────────────────────
   Not an error and never styled as one. It states the reason and offers the
   one action that changes it. */
.dash-focus-empty{
  margin-top:18px; border:1px dashed var(--line-3); border-radius:var(--r-md);
  padding:22px 20px; background:var(--sunk);
}
.dash-focus-empty b{ display:block; font-size:.98rem; color:var(--ink); margin-bottom:6px; }
.dash-focus-empty p{ font-size:.86rem; line-height:1.62; color:var(--ink-3); max-width:60ch; }
.dash-focus-empty .dash-btn{ margin-top:16px; }
.dash-focus-empty .dash-btn-amber{ box-shadow:none; }
/* .dash-btn-wire is drawn for the dark hero -- white text on a white border.
   On this light panel that is an invisible button, which is worse than no
   button: the sentence above it ends by offering an action nobody can see. */
.dash-focus-empty .dash-btn-wire{
  background:var(--page); border-color:var(--line-3); color:var(--ink);
}
.dash-focus-empty .dash-btn-wire:hover{ background:var(--chip); border-color:var(--ink-4); }

/* ═══════════════════════════════════════════════════════════════════════════
   THE SIX AREAS
   ═══════════════════════════════════════════════════════════════════════════
   The dashboard tree, drawn. Three across rather than four, because each card
   now lists what is inside it -- a candidate should be able to see the whole
   product from this one screen without opening the rail. */

.dash-grid3{ display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:16px; }
@media (max-width:1100px){ .dash-grid3{ grid-template-columns:repeat(2,minmax(0,1fr)); } }
@media (max-width:620px){ .dash-grid3{ grid-template-columns:1fr; } }

/* What is inside this area. Links where it exists, plain text where it does
   not -- a candidate is never sent to a page that is not there, and never
   left guessing whether a feature exists at all. */
.dash-card-sub{
  display:flex; flex-wrap:wrap; gap:6px; margin-top:13px;
}
.dash-card-sub span{
  font-size:.74rem; font-weight:600; line-height:1;
  padding:5px 9px; border-radius:99px; white-space:nowrap;
  background:var(--chip); color:var(--ink-2); border:1px solid transparent;
}
/* Not built yet. Outlined and dimmed rather than left out, so a candidate can
   see what is coming instead of wondering whether they have missed it. */
.dash-card-sub span.soon{ color:var(--ink-4); background:transparent; border:1px dashed var(--line-3); }
