/* Brand tokens are the approved set from mockup-approved.html's :root, which
   refines psc-checkin's palette. Component classes come in the next pass; this
   file carries the tokens plus the base type and layout rules the auth pages
   need. */
:root {
  --paper: #F4EFEA;
  --ink: #321536;
  --accent: #6E3A78;
  --accent-06: rgba(110, 58, 120, 0.08);
  --accent-12: rgba(110, 58, 120, 0.16);
  --plum: #4A2151;
  --pen: #8B768D;
  --pen-12: rgba(139, 118, 141, 0.18);
  --lilac: #BFB3C3;
  --ink-60: rgba(50, 21, 54, 0.65);
  --good: #4C7A5C;
  --good-bg: rgba(76, 122, 92, 0.12);
  --warn: #9A6B2F;
  --warn-bg: rgba(154, 107, 47, 0.12);
  --bad: #A3343A;
  --bad-bg: rgba(163, 52, 58, 0.12);
  --soft: rgba(191, 179, 195, 0.25);
  --card: #FBF8F5;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

/* ONE KNOB FOR THE WHOLE TYPE SCALE.
   Every font-size in this file is in rem, so this single value scales all of
   it together — headings, body, the small explainer and table text — and the
   proportions between them stay put. Padding, radii and grid geometry are
   deliberately still px, so turning this dial resizes the text without
   reflowing the layout into something else.
   The approved mockup was built at 16px; Cassidy asked for larger against the
   real thing on a real screen, which wins over the mockup.

   It is one knob but three settings, because the same size does not read the
   same on both devices: a phone is held a foot from your face and a monitor is
   held three, so desktop needs to be bigger to feel the same. Cassidy's words
   were that it reads too small "especially on a website browser versus a
   phone". The phone value is raised too, just less. Nothing else in the file
   is breakpoint-aware for type — these three lines are the whole story. */
html { font-size: 19px; }
@media (min-width: 900px) { html { font-size: 21px; } }
@media (min-width: 1200px) { html { font-size: 23px; } }

html, body { height: 100%; }

body {
  background: var(--paper);
  color: var(--ink);
  font-family: 'Poppins', system-ui, -apple-system, sans-serif;
  font-size: 1.0rem;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 {
  font-family: 'Playfair Display', Georgia, serif;
  font-weight: 500;
  letter-spacing: -0.01em;
}

h1 { font-size: clamp(1.75rem, 4vw, 2.375rem); color: var(--plum); }
h2 { font-size: clamp(1.375rem, 3vw, 1.75rem); }
h3 { font-size: 1.1875rem; }

a { color: var(--accent); }

.page {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  max-width: 1040px;
  margin: 0 auto;
  padding: 28px clamp(20px, 4vw, 48px) 32px;
}

.content { flex: 1; }

.brand { display: flex; align-items: center; gap: 16px; margin-bottom: clamp(24px, 5vh, 48px); }
/* The lockup already says "Purple Sky Counseling", so the auth shell's wordmark
   is now the image and only "Team Hub" stays as text — hence the rule between
   them, which reads as "this thing, belonging to that practice" rather than as
   two headings that happen to be adjacent. width/height are set in the markup
   at the file's true pixels so the header does not jump while the logo loads. */
.brandlogo { width: clamp(150px, 34vw, 200px); height: auto; }
.brandtext { display: flex; flex-direction: column; gap: 2px; padding-left: 16px; border-left: 1px solid var(--soft); }
.bt1 {
  font-family: 'Playfair Display', Georgia, serif;
  font-size: 1.5rem;
  font-weight: 600;
  line-height: 1.15;
  color: var(--plum);
}
.bt2 {
  font-size: 1.0rem;
  font-weight: 600;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--pen);
}

.sub { color: var(--ink-60); margin-top: 6px; max-width: 60ch; }
.muted { color: var(--pen); }

.stack { display: flex; flex-direction: column; gap: 10px; margin-top: 24px; align-items: flex-start; }

.btn {
  display: inline-block;
  font: inherit;
  font-weight: 500;
  text-decoration: none;
  color: #fff;
  background: var(--accent);
  border: 1px solid var(--accent);
  border-radius: 10px;
  padding: 11px 20px;
  cursor: pointer;
}
.btn:hover { background: var(--plum); border-color: var(--plum); }

.btn.ghost { background: var(--card); color: var(--ink); border-color: var(--pen-12); text-align: left; }
.btn.ghost:hover { background: var(--accent-06); border-color: var(--accent-12); }

.devrow { width: 100%; max-width: 520px; }
.devrow .btn { width: 100%; display: flex; flex-direction: column; gap: 2px; }
.devname { font-weight: 600; }
.devmeta { font-size: 0.875rem; color: var(--pen); }

.notice {
  margin-top: 18px;
  padding: 12px 16px;
  border-radius: 10px;
  background: var(--soft);
  border: 1px solid var(--pen-12);
  max-width: 60ch;
}

.warnbar {
  margin-bottom: 18px;
  padding: 10px 16px;
  border-radius: 10px;
  background: var(--warn-bg);
  border: 1px solid var(--warn);
  color: var(--warn);
  font-weight: 500;
  font-size: 0.9375rem;
}

.grants { list-style: none; margin-top: 22px; display: flex; flex-direction: column; gap: 8px; }
.grants li { display: flex; align-items: center; gap: 10px; }
.grant {
  display: inline-block;
  min-width: 46px;
  text-align: center;
  font-size: 0.8125rem;
  font-weight: 600;
  border-radius: 999px;
  padding: 2px 10px;
}
.grant.yes { background: var(--good-bg); color: var(--good); }
.grant.no { background: var(--pen-12); color: var(--pen); }

/* ---- Hub pages (ported from mockup-approved.html) ---- */

.sky {
  background: linear-gradient(160deg, #3A1B40 0%, #573062 45%, #8B6499 80%, #A987B3 100%);
  color: #F7F1EE;
  position: relative;
  overflow: hidden;
}
.sky::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 60% 40% at 78% 18%, rgba(247, 241, 238, .12), transparent 60%);
}
/* Matched to .wrap below, deliberately and by the same expression rather than
   by a copied number. They were 1040 and min(1240px, 58rem), so on a wide
   screen the brand and the nav started 100px to the RIGHT of every heading
   under them — the banner and the page did not share an edge. Anything that
   changes one of these has to change the other. */
.skyin { max-width: min(1240px, 58rem); margin: 0 auto; padding: 24px clamp(18px, 4vw, 44px) 26px; position: relative; z-index: 1; }
.brandrow { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.brandmark { display: flex; align-items: center; gap: 12px; }
/* The roundel was drawn for a white page: its mountains are nearly the same
   plum as the top of the header gradient, so dropped straight onto the band it
   would read as a dark smudge. The paper disc gives it back the background it
   was designed against, and matches the avatar treatment across the row. The
   padding keeps the brush stroke off the edge of the disc. */
.mark { width: 44px; height: 44px; border-radius: 50%; background: #F7F1EE; padding: 3px; flex: none; }
.sky .bt1 { font-family: 'Playfair Display', serif; font-size: 1.375rem; font-weight: 600; color: #F7F1EE; line-height: 1.15; }
/* font-weight is reset rather than omitted: the auth shell's .bt2 above sets
   600, and the approved mockup's header wordmark is regular weight. */
.sky .bt2 { font-size: 0.8125rem; font-weight: 400; opacity: .85; letter-spacing: .06em; text-transform: uppercase; color: #F7F1EE; }
.me { display: flex; align-items: center; gap: 10px; }
.avatar { width: 36px; height: 36px; border-radius: 50%; background: #F7F1EE; color: var(--plum); display: grid; place-items: center; font-weight: 600; font-size: 0.8125rem; }
.signout {
  font: inherit; font-size: 0.8125rem; cursor: pointer; border: 0; background: transparent;
  color: #F7F1EE; opacity: .75; text-decoration: underline; padding: 4px 0;
}
.signout:hover { opacity: 1; }
.hello { margin-top: 20px; display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.hello h1 { font-size: clamp(1.5rem, 3.5vw, 2.0rem); color: #F7F1EE; }
.hello .week { font-size: 0.8438rem; opacity: .85; }
.sky nav { margin-top: 20px; display: flex; gap: 6px; flex-wrap: wrap; }
/* 14px rather than the mockup's 15px: at the current type scale the eight tabs
   came to exactly one pixel more than the 1040px shell, which wrapped "Contact"
   onto a second row by itself. This buys 16px of slack. The nav still wraps
   cleanly by design, so a further bump to the type knob costs nothing worse
   than a tidy second row. */
.sky nav a {
  font: inherit; font-size: 0.8438rem; font-weight: 500; cursor: pointer; text-decoration: none;
  border: 0; border-radius: 999px; padding: 8px 14px;
  background: rgba(247, 241, 238, .12); color: #F7F1EE;
}
.sky nav a.on { background: var(--paper); color: var(--plum); }

/* The container scales with the type scale rather than sitting at a fixed
   1040px. A fixed width plus a bigger font is a narrower layout in the only
   unit that matters — characters per line — and it showed up as the quick-link
   tiles collapsing to 168px columns with "SimplePractice" wrapping onto three
   lines. 58rem reproduces the original 1040px at the old 18px base and grows
   from there; the px cap keeps it from outrunning a 1280 screen. */
.wrap { max-width: min(1240px, 58rem); margin: 0 auto; padding: 30px clamp(18px, 4vw, 44px) 60px; }
.wrap h2.big { font-size: 1.5rem; margin: 30px 0 4px; color: var(--plum); }
/* The mockup put its 30px gap under the nav on the section, not the first
   heading, so a page whose first block is a grid sat 30px too high here. The
   gap now lives on .wrap and the first heading adds nothing on top of it. */
.wrap h2.big:first-child, .warnbar + h2.big { margin-top: 0; }
.wrap .sub { color: var(--ink-60); font-size: 0.9062rem; max-width: 62ch; margin-top: 0; }
/* Numbers/Home occasionally stack a second .sub right under the first (e.g.
   the synthetic-data note under the page intro) — without this they read as
   one run-on paragraph. */
.wrap .sub + .sub { margin-top: 10px; }


/* Exactly four metric cards, always (My Numbers) — fixed steps rather than
   auto-fit/minmax means the fourth card never strands alone on a half-empty
   second row at common widths. See tileGrid() in layout.js for the
   data-driven grids (quick links, office directory) where the item count
   isn't a known constant. */
.cards { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin-top: 20px; }
@media (max-width: 900px) { .cards { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 520px) { .cards { grid-template-columns: 1fr; } }
.card {
  background: var(--card); border: 1px solid var(--pen-12); border-radius: 16px;
  padding: 20px 20px 18px;
}
.card h3 { margin-bottom: 8px; }
/* A card that follows a grid of other cards rather than a heading (the
   community card, the weekly-form-history card) — same 16px as the grid gap
   above it, so it reads as one more row. */
.card.spaced { margin-top: 16px; }
/* A card that is itself the link (the weekly-form nudge) has to shed the
   default anchor treatment, or it renders as underlined accent-coloured text
   in a box instead of as a card. */
a.card { display: block; text-decoration: none; color: inherit; }
a.card:hover { border-color: var(--accent); }
/* A plain list inside a card (Paperwork's "other documents" list) — no bullet
   markers, just spaced lines, so it reads like the rest of the card rather
   than like a bulleted document. */
.plainlist { list-style: none; margin: 12px 0 0; padding: 0; }
.plainlist li { padding: 6px 0; border-top: 1px solid var(--pen-12); }
.plainlist li:first-child { border-top: none; }
.metric .label { font-size: 0.8438rem; font-weight: 600; color: var(--accent); }
.metric .num { font-family: 'Playfair Display', serif; font-size: 2.375rem; line-height: 1.1; margin: 6px 0 2px; color: var(--plum); }
.metric .vs { font-size: 0.8125rem; color: var(--ink-60); }
.metric .expl { margin-top: 12px; padding-top: 12px; border-top: 1px dashed var(--pen-12); font-size: 0.8438rem; color: var(--ink-60); }
.pill { display: inline-block; font-size: 0.75rem; font-weight: 600; border-radius: 999px; padding: 3px 10px; margin-top: 8px; }
.pill.good { background: var(--good-bg); color: var(--good); }
.pill.warn { background: var(--warn-bg); color: var(--warn); }
/* Outline rather than filled, so the "synthetic" marker on My Numbers reads
   as a caveat on the number it sits next to instead of competing with the
   good/warn pills that report real status. */
/* Unlike the status pills this one never stands alone under a number — it
   trails a label or heading, so it drops .pill's top margin and keeps the
   line it belongs to tight even when the label is long enough to wrap it. */
.pill.synthetic {
  background: transparent; border: 1px solid var(--pen); color: var(--pen);
  margin-top: 0; margin-left: 6px; vertical-align: middle; white-space: nowrap;
}

/* auto-FILL, not auto-fit, and this is the whole point: auto-fill keeps the
   track width, so a tile is about the same size whether the row holds two of
   them or five. auto-fit would collapse the empty tracks and stretch two tiles
   across the entire page. Consistent tile width is what stops "Gusto / pay &
   time off" being a 570px box next to a 213px one.
   A lone tile on the last row is then simply a normal-sized tile rather than a
   stretched one, so there is no orphan to design around. That is what retired
   the per-render column counting tileGrid() used to do. */
.links { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 12px; margin-top: 16px; }
/* The old rule here forced a fixed column count between 900 and 1199, because
   "Jump back in" once sat inside a 1.4fr column and three across came to
   ~156px a tile. That block is full width now, so the squeeze it compensated
   for no longer exists, and auto-fill above already picks a sensible count at
   every width. Reinstating a fixed count would only override that badly. */
/* Two across on a phone, not one. A quick link is a two-word label and a short
   caption; given the whole width it became a 339px-wide box holding the word
   "Gusto", and a screen of those reads as enormous empty boxes rather than a
   list of links. Two across halves the box and roughly halves the scrolling.

   The last-child rule is what makes an odd count safe: with a plain two-column
   grid the final tile of an odd set sits alone in the left column with a hole
   beside it. Spanning it across both columns fills the row instead. This
   is self-healing, so a lead or admin gaining an extra tile cannot reintroduce
   the hole. */
@media (max-width: 520px) {
  .links { grid-template-columns: repeat(2, 1fr); }
  .links > :last-child:nth-child(odd) { grid-column: span 2; }
}
/* Home's quick links render as two grids, not one (see quickLinks() in
   home.js): the everyday row on top, everything else below. Without a gap
   wider than the 12px between tiles, the split reads as one grid that
   happened to wrap, and the ordering Cassidy asked for is invisible. */
.links.secondary { margin-top: 22px; }
.link {
  display: block; text-decoration: none; background: var(--card); color: var(--ink);
  border: 1px solid var(--pen-12); border-radius: 14px; padding: 14px 16px; font-size: 0.9062rem; font-weight: 500;
}
.link small { display: block; color: var(--pen); font-weight: 400; font-size: 0.7812rem; margin-top: 2px; }
.link:hover { border-color: var(--accent); }
.link.form { background: var(--accent-06); border-color: var(--accent-12); }
.link.coming { opacity: .55; cursor: not-allowed; border-style: dashed; }
.link.coming small { font-style: italic; }
.group { margin-top: 26px; }
.group h3 { color: var(--plum); font-size: 1.125rem; }
.group .own { font-size: 0.7812rem; color: var(--pen); }

/* Home used to run "This week" down a 1.4fr column with the month card beside
   it in a 1fr sidebar. Cassidy asked for the full width on 2026-08-12, and the
   sidebar had already lost its other occupant ("Who to ask" moved to a
   full-width row near the foot), so the two-column wrapper is gone entirely
   rather than left holding one card.

   The week's cards then flow instead of stacking: at full width a single
   column would draw each nudge as one very wide, very thin bar. auto-fill
   rather than auto-fit, because a week with one card should leave that card a
   readable width instead of stretching it across the whole page. */
.cards.week { grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); }
@media (max-width: 520px) { .cards.week { grid-template-columns: 1fr; } }
/* Now a full-width row near the foot of Home rather than the top of the
   sidebar. It is a reference card you go looking for when something has gone
   wrong, not something to read past every morning — which is the same reason it
   already dropped to the end of the stack on a phone.
   Full width means the four rows lay out in columns instead of one long list,
   so the card stays short. auto-fit here rather than auto-fill: there are
   exactly four rows and they SHOULD share the width evenly. */
.ask { margin-top: 20px; }
.ask .rows { display: grid; grid-template-columns: 1fr; }
.ask .row { display: flex; justify-content: space-between; gap: 10px; padding: 8px 0; border-top: 1px solid var(--soft); font-size: 0.875rem; }
.ask .row:first-of-type { border-top: 0; }
/* With the rows in columns, "first of type" only clears the border on the very
   first cell, leaving a stray rule above the first row of every other column.
   Each column's top cell needs it cleared instead. */
/* One column, half the page. Cassidy, 2026-08-12: full width made four short
   rows look like a form. A single column of four keeps each question next to
   its answer instead of splitting them across the page, and the card stops
   competing with Jump back in above it. */
@media (min-width: 760px) {
  .ask { max-width: 52%; }
  /* Except the flow chart on Home, which spans the page (Cassidy,
     2026-10-06): its topics lay out side by side and need the room. */
  .ask.askflow { max-width: none; }
}
.ask .row span:last-child { color: var(--accent); font-weight: 500; text-align: right; }
/* Raising the type scale put this sidebar back into exactly the bind the
   900px stack breakpoint above was added to fix: at the desktop setting the
   question and its answer fight over ~348px and both break mid-phrase
   ("Billing or claims / question" beside "Billing / form"). Allowing the row
   to wrap drops the answer onto its own line instead, so each half gets the
   full width. Nothing moves at sizes where both already fit. */
.ask .row { flex-wrap: wrap; }
.ask .row span:first-child { flex: 1 1 auto; min-width: 0; }
.ask .row span:last-child { margin-left: auto; }
/* The answers are links now. They already sit in the accent colour, which on
   its own is how every other link on the page announces itself — so an
   underline at rest would make this one card louder than the rest. It appears
   on hover and on keyboard focus instead, which is where it is actually doing
   work. Colour is inherited from the span so the two states cannot drift. */
.ask .row a { color: inherit; text-decoration: none; }
.ask .row a:hover, .ask .row a:focus-visible { text-decoration: underline; }
.duecard { border-left: 3px solid var(--accent); }
.duecard b { font-weight: 600; }
.duecard .when { font-size: 0.7812rem; color: var(--pen); margin-top: 2px; }
.duecard.ok { border-left-color: var(--good); }
.duecard.lilac { border-left-color: var(--lilac); }
.duecard.warn { border-left-color: var(--warn); }
/* The website queue card on Home carries a real button to the queue, not a
   whole-card link, because it sits among cards that ARE links and should read
   as the one with an action on it. */
.queuebtn {
  display: inline-block; margin-top: 10px; font-size: 0.8125rem; font-weight: 500;
  border-radius: 999px; padding: 8px 18px; background: var(--accent); color: var(--paper); text-decoration: none;
}
.queuebtn:hover { background: var(--plum); }
.queuebtn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.sitetracker-scope + .sitetracker-scope { margin-top: 10px; padding-top: 10px; border-top: 1px dashed var(--pen-12); }

.chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.chip { font-size: 0.8125rem; font-weight: 500; border-radius: 999px; padding: 5px 13px; background: var(--good-bg); color: var(--good); }
.chip.pending { background: var(--warn-bg); color: var(--warn); }
.chip.neutral { background: var(--accent-06); color: var(--accent); }
.rules { margin-top: 12px; background: var(--accent-06); border-radius: 12px; padding: 12px 16px; font-size: 0.8125rem; color: var(--ink-60); }
.rules b { color: var(--ink); }
table.plain { width: 100%; border-collapse: collapse; margin-top: 10px; font-size: 0.8438rem; }
table.plain td { padding: 7px 0; border-top: 1px solid var(--soft); }
/* The right-hand column is always a short date or status ("Aug 26", "say
   hi"); letting it wrap mid-value to buy the first column a few pixels reads
   as a broken row. */
/* The last cell used to right-align and go grey, which suited the two-column
   "label / value" tables it was written for and was wrong everywhere else: in
   any table of figures the final column is a figure like the rest, and it was
   the only one pushed to the edge. Scoped to the two-column case. */
table.plain tr:has(td:nth-child(2):last-child) td:last-child { text-align: right; color: var(--pen); white-space: nowrap; }
table.plain tr:first-child td { border-top: 0; }
/* .pill carries a top margin for the metric cards it was designed for; in a
   table cell that margin pushes the status pill out of line with the week
   label beside it. */
table.plain .pill { margin-top: 0; }

/* Every table is wrapped in one of these. A table that outgrows its card
   scrolls inside the card rather than widening the page — the roster feeds
   these rows, so a long name or a new column must not be able to introduce a
   body-level horizontal scrollbar. */
.tablescroll { overflow-x: auto; }

/* Same self-healing column count as .links (see tileGrid() in layout.js) —
   the directory's card count changes whenever an office or group is added
   or removed, so a fixed breakpoint would eventually drift back into the
   orphan bug. */
/* Office cards hold anywhere from two people to fifteen. A row-based grid
   ties every card in a row to the tallest one, so Murray's roster left most
   of a screen of empty paper beside Leadership, and a card count that didn't
   divide evenly stranded the last card on its own row. Flowing the cards down
   columns instead removes both: each card is as tall as its own roster, the
   columns fill continuously, and there is no last row for anything to be
   stranded on. Reading order is down a column, then over. */
/* Every office is a full-width card, stacked, with the flow moved INSIDE each
   one (.peoplecols). This replaced a three-column masonry of cards: a card the
   masonry could not break set a floor on its column's height, so Murray's 3790
   pixels forced one column to 6972 against a 4500 ideal. Column-balancing
   cannot solve a block taller than the balanced column. */
.sitewide { margin-top: 20px; }
.sitewide > .card { margin-bottom: 16px; }
/* An office's leads, across the top of its card in the same three-column
   rhythm as the people below. Grid rather than `columns` so they fill left to
   right: multi-column flows top-to-bottom first, which put lead two under lead
   one instead of beside it. */
.leadrow {
  display: grid; grid-template-columns: repeat(3, 1fr); column-gap: 24px;
  margin-top: 4px; padding-bottom: 4px; border-bottom: 1px solid var(--soft);
}
/* The row's own bottom rule is the separator, so the per-person top borders
   would draw a second line across every lead. */
.leadrow .person { border-top: 0; }
@media (max-width: 900px) { .leadrow { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 520px) { .leadrow { grid-template-columns: 1fr; } }
/* Three columns of people inside a wide card, dropping with the page. One
   block per building, with the heading full-width above it (see siteCard), so
   a person row is the only thing that ever flows across a column boundary. */
.peoplecols { columns: 3; column-gap: 24px; margin-top: 4px; }
.peoplecols .person { break-inside: avoid; }
/* A person row's top border is the separator between rows, so the first row in
   EVERY column would otherwise open with a stray rule under the heading. */
.peoplecols .person:first-of-type { border-top: 0; }
@media (max-width: 900px) { .peoplecols { columns: 2; } }
@media (max-width: 520px) { .peoplecols { columns: 1; } }
/* Jump list at the top of Contact. Wraps rather than scrolls sideways, because
   ten offices on a phone is three tidy rows and a horizontal scroller hides
   whichever office happens to fall off the right edge. */
.jumplist { display: flex; flex-wrap: wrap; gap: 8px; margin: 16px 0 4px; }
.jumplist a {
  font-size: 0.8125rem; font-weight: 500; text-decoration: none;
  border: 1px solid var(--pen-12); border-radius: 999px; padding: 6px 14px;
  background: var(--accent-06); color: var(--plum);
}
.jumplist a:hover, .jumplist a:focus-visible { background: var(--accent); color: #F7F1EE; }
/* Cards are full width and stacked, so a jump-list click is a real scroll on
   every screen. The highlight marks which card you landed on; scroll-margin
   keeps its heading clear of the viewport edge. */
.site { scroll-margin-top: 16px; }
.site:target { box-shadow: 0 0 0 2px var(--accent); }
.site h3 { color: var(--plum); font-size: 1.125rem; margin-bottom: 2px; }
.site .addr { font-size: 0.7812rem; color: var(--pen); margin-bottom: 10px; }
.site .building { font-size: 0.75rem; font-weight: 600; color: var(--pen); text-transform: uppercase; letter-spacing: .04em; margin: 12px 0 2px; }
.site .building:first-of-type { margin-top: 4px; }
.site .empty { font-size: 0.7812rem; color: var(--pen); font-style: italic; padding: 4px 0; }
.star { color: var(--accent); font-weight: 600; padding-left: 2px; }
/* The credential and its second-office star wrap together or not at all, and
   both stay INLINE with the name. `.person .who span` stacks every span in
   the block, which is right for the role, email and phone and wrong for these
   two — without this the star landed on a line of its own. */
.cred { white-space: nowrap; }
.person .who b .cred,
.person .who b .star { display: inline; font-size: inherit; color: inherit; }
.person .who b .star { color: var(--accent); }
/* Sits after the role on the same line, so a virtual-only person reads as
   "Therapist · virtual only" rather than gaining a row the others do not. */
.virtualtag { font-size: 0.6875rem; color: var(--pen); font-style: italic; margin-left: 6px; white-space: nowrap; }
/* Contact: a card pointing at a page that answers more than its own list can
   (the admin card -> /admin-team). */
.sitemore { font-size: 0.7812rem; margin: 0 0 10px; }
/* Home's Who to ask, and the Admin team page it leads to. */
.askmore { font-size: 0.7812rem; margin: 10px 0 0; }
.admingrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(290px, 1fr)); gap: 16px; margin-top: 20px; align-items: start; }
.admincard .person { border-top: 0; padding-top: 0; }
/* The plain-English job, which is the line people come to this page to read,
   so it carries the weight rather than the formal title above it. */
.adminmain { font-size: 0.9375rem; font-weight: 600; color: var(--plum); margin: 10px 0 0; }
.admincovers { font-size: 0.8125rem; color: var(--pen); margin: 4px 0 0; }
/* overflow-wrap, not word-break: break-all splits at whatever character lands
   on the edge, which broke "kylie@purpleskycounseling.com" mid-domain. Same
   rule the directory's .mail already uses, for the same address. */
.adminmail { display: inline-block; font-size: 0.7812rem; margin-top: 10px; overflow-wrap: anywhere; }
.site .footnote { font-size: 0.7812rem; color: var(--pen); margin-top: 10px; padding-top: 8px; border-top: 1px solid var(--soft); }
.person { display: flex; align-items: center; gap: 10px; padding: 7px 0; border-top: 1px solid var(--soft); font-size: 0.875rem; }
.person:first-of-type { border-top: 0; }
/* One class for both the photo and the initials fallback, so a person with a
   headshot and a person without sit on exactly the same baseline and the rows
   never jump height between them. object-fit keeps a face centred inside the
   circle regardless of the source crop. */
.dot {
  width: 44px; height: 44px; border-radius: 50%; background: var(--accent-12);
  color: var(--plum); display: grid; place-items: center; font-size: 0.8125rem;
  font-weight: 600; flex-shrink: 0; overflow: hidden;
}
img.dot { object-fit: cover; display: block; }
.person .who { min-width: 0; }
.person .who b { display: block; font-weight: 500; }
/* Role, email and phone each get their own line. Joined onto one line they
   only fit while the title is short and the address is average — a clinical
   director's full title next to a 37-character address wrapped mid-word in
   the middle of a name. */
.person .who span { display: block; font-size: 0.7812rem; color: var(--pen); }
/* A named programme somebody runs (DBT, Play Therapy). Its own line under the
   role rather than another item in it: the role line already carries up to
   three facts for a lead who also supervises, and a fourth stops scanning.
   Specificity matches `.person .who span` above deliberately — that rule
   blockifies every span in the row, which would stretch this pill the full
   width of the card. Same trap `.cred`/`.star` had to be rescued from. */
.person .who .programtag {
  display: inline-block; margin-top: 3px; padding: 1px 8px; border-radius: 10px;
  background: var(--accent-12); color: var(--plum); font-size: 0.6875rem;
  font-weight: 600; white-space: nowrap;
}
/* Work email is the longest unbreakable string the directory renders and it
   comes from the roster, so the break opportunity is forced rather than left
   to whether today's longest address happens to fit. */
.person .who .mail { overflow-wrap: anywhere; }
/* The work-phone span is a second, optional line after role/email — without
   this it runs straight into the email with no separator or break. */
.person .who .phone { display: block; margin-top: 1px; }

/* The mission statement closes every Home page, and at 1.0625rem it read as a
   caption — the last small grey thing on the way to the footer. It is the
   practice's reason for existing, so it now carries the weight of a section
   heading: Playfair at the same size as an h2, semibold, with a short rule
   above it so it reads as an intentional close rather than leftover text.
   Sized in rem, so it rides the three type-scale settings above with
   everything else. */
.mission { margin-top: 46px; padding-top: 30px; text-align: center; }
.mission p {
  font-family: 'Playfair Display', serif;
  font-size: clamp(1.375rem, 2.6vw, 1.75rem);
  font-weight: 600;
  line-height: 1.3;
  color: var(--plum);
  max-width: 26ch;
  margin: 0 auto;
}
/* The rule is a centered short bar rather than a full-width border, which
   would have read as a divider between sections instead of a flourish on
   this one. ::before on the block, so it needs no extra markup — and no
   inline style, which the CSP would drop. */
.mission::before {
  content: '';
  display: block;
  width: 54px;
  height: 3px;
  border-radius: 999px;
  background: var(--accent);
  margin: 0 auto 22px;
}
/* The five value names under the mission. Names only: the paragraphs live on
   Policies & Onboarding, and Home is a page people scan on the way to
   something else, so anything longer than a word each would be scrolled past
   rather than read. They are not links — the value of putting them here is
   that they are seen daily, not that they are a route to the full text. */
.valuenames {
  margin-top: 18px;
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 8px 10px;
}
.valuenames span {
  font-size: 0.7812rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
  background: var(--accent-06);
  border-radius: 999px;
  padding: 5px 13px;
}

/* Values on Policies & Onboarding.
   Flex, not grid, and this is the whole reason: there are five of them, and a
   fixed or auto-fit GRID puts three on the first row and then leaves the
   remaining two sitting at a third of the width against a stretch of empty
   page. Flex items that are allowed to grow (flex-grow 1 on a 260px basis)
   share out whatever the row actually has, so three across becomes two
   half-width cards underneath and both rows reach the same edge. It also means
   the block never has to be re-tuned if a sixth value is added or one is cut:
   any count fills its rows, and even a lone card on the last row stretches
   full width, which reads as deliberate rather than stranded. */
.values {
  margin-top: 14px;
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
}
/* 320px basis, not 260: the shell is ~1150px at the desktop type scale, where a
   260px basis fits FOUR across and leaves the fifth alone on its own row. 320
   is wide enough that a fourth card cannot fit and narrow enough that three
   still do, which is what pins the layout to three-then-two. */
.value {
  flex: 1 1 320px;
  position: relative;
  background: var(--card);
  border: 1px solid var(--soft);
  border-radius: 14px;
  padding: 18px 20px;
}
/* The numerals do two things: they make five items read as one considered set
   rather than five loose cards, and they carry the reading order across a row
   break that the eye would otherwise have to guess at. Sized and coloured to
   sit behind the name, not compete with it. */
.valuenum {
  display: block;
  font-family: 'Playfair Display', serif;
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--lilac);
  margin-bottom: 2px;
}
.value h4 {
  font-family: 'Playfair Display', serif;
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--plum);
  margin-bottom: 8px;
}
.value p { font-size: 0.875rem; line-height: 1.6; color: var(--ink-60); }

/* ---- My Profile: the photo upload spot ---- */

.photocard { margin-top: 18px; }
/* Wraps to a stack on a phone, which is where most of these uploads will
   actually happen — the photo someone wants is already on their camera roll. */
.photorow { display: flex; gap: 22px; align-items: flex-start; flex-wrap: wrap; margin-top: 16px; }
.photoside { display: flex; gap: 12px; }
.photoform { flex: 1 1 260px; display: flex; flex-direction: column; align-items: flex-start; gap: 10px; }

/* Circular at the same proportion as the directory's avatars, so what this
   card shows is what the rest of the hub will show, including the crop. */
.photo-current {
  width: 128px; height: 128px; border-radius: 50%;
  object-fit: cover; background: var(--card); border: 1px solid var(--soft);
}
.photo-none {
  display: grid; place-items: center;
  font-size: 2.25rem; font-weight: 500; color: var(--accent); background: var(--accent-06);
}
/* The chosen photo appears beside the current one rather than replacing it, so
   the comparison is direct instead of from memory. */
.photo-preview { border: 2px solid var(--accent); }

.photowhere { font-size: 0.875rem; color: var(--ink-60); line-height: 1.5; }
.photonote { font-size: 0.7812rem; color: var(--pen); line-height: 1.5; }

/* The file input is replaced by its own label: a bare input renders as a
   browser-styled button that ignores everything in this file. It stays in the
   DOM and focusable rather than display:none, which would take it out of the
   keyboard order and off screen readers. */
.filelabel {
  display: inline-flex; align-items: center; cursor: pointer;
  border: 1px solid var(--accent); border-radius: 999px;
  padding: 9px 18px; font-size: 0.875rem; font-weight: 500; color: var(--accent);
  background: var(--accent-06);
}
.filelabel:hover { background: var(--accent-12); }
.filelabel input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.filelabel:focus-within { outline: 2px solid var(--accent); outline-offset: 2px; }

button.primary {
  font: inherit; font-size: 0.875rem; font-weight: 500; cursor: pointer;
  border: 0; border-radius: 999px; padding: 10px 22px;
  background: var(--accent); color: var(--paper);
}
button.primary:disabled { background: var(--pen-12); color: var(--pen); cursor: default; }

.photostatus { font-size: 0.8125rem; color: var(--ink-60); min-height: 1.2em; }
.photostatus.bad { color: var(--warn); }
.photostatus.good { color: var(--good); }

.photo-remove { margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--soft); }
.photo-remove small { display: block; margin-top: 4px; font-size: 0.7812rem; color: var(--pen); }
button.linkish {
  font: inherit; font-size: 0.8125rem; cursor: pointer; border: 0; background: transparent;
  color: var(--accent); text-decoration: underline; padding: 0;
  position: relative;
}
/* "Remove" and "View as" render about 24px tall, well under the ~44px a finger
   needs, and they sit in dense rows where the neighbouring target is a person's
   document or post — so a near miss is not harmless. This grows the hit area
   without moving anything: an absolutely positioned overlay adds no height to
   the row, where padding would have pushed every row apart. */
button.linkish::after {
  content: '';
  position: absolute;
  inset: -11px -10px;
}
/* Same treatment for the header's sign-out, which measures 32px. */
.signout { position: relative; }
.signout::after { content: ''; position: absolute; inset: -8px -10px; }

/* ---- Photo Wall ---- */

.composer { margin: 16px 0 26px; }
.composer .photoform { margin-top: 14px; }
.caplabel { display: flex; flex-direction: column; gap: 5px; width: 100%; max-width: 480px; font-size: 0.8125rem; color: var(--ink-60); }
.caplabel input {
  font: inherit; font-size: 0.875rem; color: var(--ink);
  border: 1px solid var(--soft); border-radius: 10px; padding: 9px 12px; background: var(--paper);
}
.caplabel input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* The confirmation is a full sentence rather than "I confirm", and it is not
   pre-ticked. It is the only thing standing between a hurried upload and a
   client's face on an internal wall, so it has to be read to be answered. */
/* 700px, not the 480px this shipped at (Cassidy, 2026-09-21: it should not
   break across two lines). Measured, not guessed: the sentence renders at
   643px, plus the 16px box and the 9px gap, so it needs 668px and anything
   under that wraps. 700 leaves headroom for font rendering. It keeps a
   max-width rather than dropping one so the line still wraps on a phone,
   where two lines are correct and unavoidable. */
.confirm { display: flex; align-items: flex-start; gap: 9px; max-width: 700px; font-size: 0.8125rem; color: var(--ink-60); line-height: 1.5; }
.confirm input { margin-top: 3px; flex: none; width: 16px; height: 16px; accent-color: var(--accent); }

.postpreview { max-width: 260px; width: 100%; border-radius: 12px; border: 2px solid var(--accent); }

/* The wall itself. Same flex-with-grow approach as the values block, and for
   the same reason: the post count is whatever the team has posted, so any
   fixed column count is wrong at some of them. Growing items mean the last row
   fills instead of trailing off. */
.wall { display: flex; flex-wrap: wrap; gap: 16px; margin-top: 8px; }
.post {
  flex: 1 1 300px;
  background: var(--card);
  border: 1px solid var(--soft);
  border-radius: 14px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
/* Fixed aspect with cover, so a wall of mixed portrait and landscape photos
   still reads as a grid. The photo is stored uncropped; only the tile crops. */
.postimg { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; display: block; background: var(--accent-06); }

/* A post holds one attachment or several. One fills the card as before; two or
   more become a grid inside it, so five photos from one lunch read as one
   moment rather than five posts burying everything else on the wall. The count
   arrives as a class (n2/n3/n4) because style-src has no 'unsafe-inline' and a
   style attribute carrying it would be dropped. */
.postitems { display: block; }
.postitems.gallery { display: grid; gap: 2px; }
.postitems.gallery.n2 { grid-template-columns: repeat(2, 1fr); }
.postitems.gallery.n3 { grid-template-columns: repeat(3, 1fr); }
.postitems.gallery.n4 { grid-template-columns: repeat(2, 1fr); }
/* In a gallery each tile is square, so rows line up however many there are.
   A single attachment keeps the wider 4:3 it was designed at. */
.postitems.gallery .postimg { aspect-ratio: 1 / 1; }
.postitem { position: relative; display: block; }

/* A photo opens full size. The tile is a <button> so it is keyboard-reachable
   and announced as something that does anything at all, which a bare <img>
   never is; these three lines undo the button chrome so it still looks like a
   photo. The zoom is a progressive extra — with JavaScript off the button is
   inert and the wall reads exactly as it did before. */
button.postitem {
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  cursor: zoom-in;
}
button.postitem:focus-visible { outline: 3px solid var(--accent); outline-offset: -3px; }

/* The viewer itself. <dialog> is doing the work here — showModal() gives the
   backdrop, the Escape key and the focus trap for free, so this is only
   painting. */
.lightbox {
  border: 0;
  padding: 0;
  /* The dim lives on the dialog, not only on ::backdrop. The dialog is sized
     to the whole viewport so the two cover the same area, and putting the
     colour here means the photo is never shown against a half-lit page if
     ::backdrop is composited oddly — which is exactly what it looked like
     when this was checked. ::backdrop keeps its colour below as well, so
     whichever one paints, the result is the same. */
  background: rgba(32, 18, 38, 0.92);
  max-width: 100vw;
  max-height: 100vh;
  width: 100%;
  height: 100%;
  overflow: hidden;
}
.lightbox::backdrop { background: rgba(32, 18, 38, 0.86); }
.lightbox form { display: flex; flex-direction: column; height: 100%; margin: 0; }
.lightboximg {
  flex: 1;
  min-height: 0;
  width: 100%;
  object-fit: contain;
  /* The dialog's own backdrop shows through, so the image sits on the photo
     and nothing else. */
  background: none;
}
.lightboxcap {
  flex: 0 0 auto;
  color: var(--paper);
  font-size: 0.875rem;
  line-height: 1.5;
  text-align: center;
  padding: 12px 16px 18px;
  margin: 0;
  max-width: 70ch;
  align-self: center;
}
.lightboxclose {
  align-self: flex-end;
  margin: 10px 12px 0;
  border: 0;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.16);
  color: var(--paper);
  font: inherit;
  font-size: 1.125rem;
  line-height: 1;
  padding: 9px 14px;
  cursor: pointer;
}
.lightboxclose:hover { background: rgba(255, 255, 255, 0.28); }
.lightboxclose:focus-visible { outline: 3px solid var(--paper); outline-offset: 2px; }

/* A PDF tile is the rendered first page under a link to the document, not a
   generic file icon: you see which document it is before deciding to open it.
   The whole tile is the link, because a small "open PDF" line under a picture
   is the thing nobody notices. */
.pdfitem { text-decoration: none; color: inherit; }
.pdfitem .postimg { background: #fff; object-fit: contain; }
.pdfbadge {
  position: absolute; top: 8px; left: 8px;
  font-size: 0.6875rem; font-weight: 600; letter-spacing: .08em;
  background: var(--plum); color: var(--paper);
  border-radius: 999px; padding: 3px 9px;
}
/* Sits over the foot of the page image, so the filename is readable without
   stealing a line of card height from the caption. */
.pdfname {
  position: absolute; left: 0; right: 0; bottom: 0;
  font-size: 0.75rem; color: #fff;
  background: rgba(50, 21, 54, .78);
  padding: 6px 10px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pdfitem:hover .pdfname, .pdfitem:focus-visible .pdfname { text-decoration: underline; }

/* What you picked, before you post it. */
.picked { display: flex; flex-wrap: wrap; gap: 8px; }
.pickeditem { position: relative; display: block; width: 84px; height: 84px; }
.pickeditem img { width: 100%; height: 100%; object-fit: cover; border-radius: 10px; border: 1px solid var(--soft); background: #fff; }
.pickeditem.ispdf img { object-fit: contain; }
.pickedtag {
  position: absolute; bottom: 4px; left: 4px;
  font-size: 0.5625rem; font-weight: 600; letter-spacing: .06em;
  background: var(--plum); color: var(--paper);
  border-radius: 999px; padding: 1px 6px;
}
.post figcaption { padding: 14px 16px 15px; display: flex; flex-direction: column; gap: 10px; flex: 1; }
.postcap { font-size: 0.875rem; line-height: 1.5; color: var(--ink); }
.postmeta { display: flex; align-items: center; gap: 8px; font-size: 0.7812rem; color: var(--pen); margin-top: auto; }
/* Only the size is overridden. Everything else about a dot — the circle, the
   centred initials, the cover-fit for a photo — comes from the base .dot rule
   the directory uses, so the two stay in step. */
.postmeta .dot { width: 28px; height: 28px; font-size: 0.6875rem; }
/* Pushed to the far end so "Remove" is never adjacent to the name it would be
   mistaken for acting on. */
.postdel { margin-left: auto; }
.postwhen { white-space: nowrap; }

/* The Home peek: a full-width row of thumbnails, the whole card a link to the
   wall. Full width because a real team photo is wide — in the right-hand column
   it overflowed and pushed the layout out of shape.

   Each thumbnail is a fixed-height, equal-width cell that crops to fill, so a
   row of mixed portrait and landscape photos stays a tidy band instead of
   taking its height from whichever picture happens to be tallest. */
.wallpeek { display: block; text-decoration: none; color: inherit; margin-top: 20px; }
.wallpeek:hover { border-color: var(--accent-12); }
.wallstrip { display: flex; gap: 8px; margin-top: 12px; }
.wallthumb {
  flex: 1 1 0;
  min-width: 0;
  height: clamp(120px, 16vw, 190px);
  object-fit: cover;
  border-radius: 10px;
  background: var(--accent-06);
}
/* On a phone four across would be thumbnails of nothing. Two rows of two, at a
   height that still shows a face. */
@media (max-width: 620px) {
  .wallstrip { flex-wrap: wrap; }
  .wallthumb { flex: 1 1 calc(50% - 4px); height: 132px; }
}

/* ---- My Profile: compliance paperwork ---- */

.doccard { margin-top: 18px; }
.doclist { list-style: none; margin: 14px 0 4px; display: flex; flex-direction: column; gap: 2px; }
.docrow { display: flex; align-items: center; gap: 12px; padding: 10px 0; border-top: 1px solid var(--soft); }
.docrow:first-child { border-top: 0; }

/* A thumbnail rather than a file icon, for the same reason the wall renders
   PDFs: "License" and "Liability insurance" look identical as rows of text,
   and the picture is how you tell at a glance that you attached the right
   thing. */
.docthumb { position: relative; flex: none; display: block; width: 56px; height: 56px; }
.docthumb img { width: 100%; height: 100%; object-fit: cover; border-radius: 8px; border: 1px solid var(--soft); background: #fff; }
.docpdf {
  position: absolute; bottom: -3px; left: -3px;
  font-size: 0.5625rem; font-weight: 600; letter-spacing: .06em;
  background: var(--plum); color: var(--paper);
  border-radius: 999px; padding: 1px 6px;
}
.docwho { min-width: 0; flex: 1; display: flex; flex-direction: column; }
.docwho a { text-decoration: none; color: var(--accent); }
.docwho a:hover { text-decoration: underline; }
.docwho b { font-weight: 500; }
.docwho span { font-size: 0.7812rem; color: var(--pen); overflow-wrap: anywhere; }
.docdel { margin-left: auto; flex: none; }

/* A certificate row plus its (closed) edit form. The rule .docrow carries for
   its own separator moves out here, because the row is no longer the direct
   child of the list and :first-child would put a line above the first one. */
.doccert { display: flex; flex-direction: column; }
.doccert .docrow { border-top: 0; }
.doccert + .doccert { border-top: 1px solid var(--soft); }
.docedit { margin: 0 0 12px 68px; }
.docedit > summary {
  font-size: 0.7812rem; color: var(--accent); cursor: pointer;
  width: fit-content; padding: 2px 0;
}
.docedit > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
.docedit form { display: flex; flex-direction: column; gap: 10px; margin-top: 10px; }
.docedit .photonote { margin: 0; }
.docedit button { align-self: flex-start; }
@media (max-width: 560px) { .docedit { margin-left: 0; } }

.docform { margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--soft); }
.caplabel select {
  font: inherit; font-size: 0.875rem; color: var(--ink);
  border: 1px solid var(--soft); border-radius: 10px; padding: 9px 12px; background: var(--paper);
}
.caplabel select:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* ---- Paperwork overview (directors) ---- */

.paperwork th { text-align: left; font-weight: 600; font-size: 0.7812rem; color: var(--pen); text-transform: uppercase; letter-spacing: .05em; padding-bottom: 6px; }
.paperwork td { vertical-align: middle; }
/* Three states, not two. "On file but no expiry recorded" is a real answer and
   has to look different from both a current policy and a missing one, or the
   page claims more than the data supports. */
.pill {
  display: inline-block; font-size: 0.7188rem; font-weight: 600;
  border-radius: 999px; padding: 2px 10px; white-space: nowrap;
}
.pill.yes { background: var(--good-bg); color: var(--good); }
.pill.part { background: var(--warn-bg); color: var(--warn); }
.pill.no { background: var(--pen-12); color: var(--pen); }
.pill.bad { background: var(--bad-bg); color: var(--bad); }
.paperlink { font-size: 0.7188rem; margin-left: 6px; }
/* Which certificate a Drive-held policy is, on its own line under the pill. The
   register gives a policy number and a filename and no link, so this is the whole
   of how somebody finds the document. */
.papernote { display: block; margin-top: 3px; font-size: 0.6875rem; color: var(--pen); }
.newtag {
  margin-left: 6px; font-size: 0.6562rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .06em;
  background: var(--accent); color: var(--paper);
  border-radius: 999px; padding: 1px 7px;
}

/* ---- Announcements (top of Home) ---- */

/* A full-width bar across the top of Home, not a card in a column. Tinted and
   ruled down the leading edge so it reads as the practice speaking, distinct
   from the "This week" cards below, which are one person's own to-do list.

   Copy left, action right, so the band stays shallow. Stacked on a phone,
   where side-by-side would leave the text a few words wide. */
.announce {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: clamp(16px, 4vw, 44px);
  flex-wrap: wrap;
  margin: 4px 0 24px;
  padding: 20px clamp(18px, 3vw, 28px);
  border-left: 3px solid var(--accent);
  border-radius: 14px;
  background: var(--accent-06);
}
.anncopy { flex: 1 1 420px; min-width: 0; }
.annaction { flex: 0 0 auto; }
.anntag {
  display: inline-block; margin-bottom: 4px;
  font-size: 0.6875rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .08em;
  color: var(--accent);
}
/* h2 rather than h3: it is a page-level section sitting directly under the
   page's h1, and an h1 -> h3 jump is a real defect for anyone navigating by
   headings. Sized to match what it looked like as an h3. */
.anntitle { color: var(--plum); font-size: 1.125rem; }
.annlead { margin-top: 5px; font-size: 0.875rem; line-height: 1.5; color: var(--ink); }

/* A posted announcement is typed into a textarea, so its body arrives as
   paragraphs and bullets rather than one line of text (see richText in
   layout.js). These rules are what make the shape somebody typed visible; both
   places the same body is read — the bar on Home and the list on Leadership —
   share them, so a notice never looks like two different notices.

   Bullets are drawn with a dot rather than list-style, matching .annpoints
   above and sidestepping the padding reset at the top of this file. */
/* Every block after the first is spaced from the one above it, whatever the
   two are: paragraph then list, list then paragraph, or two paragraphs. Naming
   the pairs instead is how a paragraph sitting under a list ends up glued to
   the last bullet. */
.annlead > * + *, .annbody > * + * { margin-top: 8px; }
.annlead ul, .annbody ul {
  list-style: none;
  display: flex; flex-direction: column; gap: 3px;
}
.annlead li, .annbody li { position: relative; padding-left: 14px; }
.annlead li::before, .annbody li::before {
  content: ''; position: absolute; left: 0; top: 0.55em;
  width: 5px; height: 5px; border-radius: 50%; background: var(--lilac);
}
.annlead strong, .annbody strong { font-weight: 600; color: var(--plum); }
/* A link is underlined as well as coloured: the bar is read at a glance, and
   colour on its own is not a signal everyone receives. A long address breaks
   inside itself rather than pushing the card sideways on a phone. */
.annlead a, .annbody a {
  color: var(--accent); text-decoration: underline; text-underline-offset: 2px;
  overflow-wrap: anywhere;
}
.annlead a:hover, .annbody a:hover { color: var(--plum); }
/* The points run as a wrapped row rather than a bulleted column: four short
   facts stacked vertically is what made this a tall card instead of a bar. */
.annpoints {
  list-style: none;
  margin: 10px 0 0;
  display: flex; flex-wrap: wrap; gap: 4px 18px;
}
.annpoints li { position: relative; padding-left: 13px; font-size: 0.8125rem; line-height: 1.45; color: var(--ink-60); }
.annpoints li::before { content: ''; position: absolute; left: 0; top: 0.55em; width: 5px; height: 5px; border-radius: 50%; background: var(--lilac); }
.annfoot { margin-top: 9px; font-size: 0.8125rem; line-height: 1.45; color: var(--pen); }
.annlink {
  display: inline-block;
  font-size: 0.875rem; font-weight: 500; text-decoration: none; white-space: nowrap;
  background: var(--accent); color: var(--paper);
  border-radius: 999px; padding: 11px 28px;
}
.annlink:hover { background: var(--plum); }

/* ---- View as (directors) ---- */

/* Deliberately loud and never dismissible. The failure this prevents is a
   director forgetting whose view they are in and reading someone else's numbers
   as their own. It uses the plum band rather than the warning amber because
   this is a normal thing to be doing, not an error state. */
.previewbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; flex-wrap: wrap;
  margin-bottom: 18px; padding: 12px 18px;
  border-radius: 10px;
  background: var(--plum); color: var(--paper);
  font-size: 0.8438rem; line-height: 1.45;
}
.previewbar b { font-weight: 600; }
.previewbar button {
  font: inherit; font-size: 0.8125rem; font-weight: 500; cursor: pointer;
  border: 1px solid rgba(247, 241, 238, .5); border-radius: 999px;
  background: transparent; color: var(--paper); padding: 6px 16px; white-space: nowrap;
}
.previewbar button:hover { background: rgba(247, 241, 238, .14); }

.viewaslist { list-style: none; display: flex; flex-direction: column; gap: 0; }
.viewaslist .person { display: flex; align-items: center; gap: 12px; padding: 9px 0; border-top: 1px solid var(--soft); }
.viewaslist .person:first-child { border-top: 0; }
.viewasbtn { margin-left: auto; }

.wrap footer { margin-top: 48px; text-align: center; font-size: 0.7812rem; color: var(--pen); }

/* ---- Deep Dive month panels (Trainings) ---- */

/* Two disclosure panels standing in for the "last month / this month" buttons
   Cassidy asked for. <details> rather than a button plus script: script-src is
   'self' with no 'unsafe-inline', and this needs no JavaScript at all, so it
   still works on a phone with a bad connection and it prints.

   A 46px minimum on the summary because that is the tap target this app
   settled on after 24px "Remove" and "View as" controls proved too small on a
   phone, which is where the team actually reads this. */
.ddpanels { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 12px; margin-top: 16px; }
.ddpanel { background: var(--card); border: 1px solid var(--soft); border-radius: 12px; overflow: hidden; }
.ddpanel summary {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  min-height: 46px; padding: 10px 16px; cursor: pointer;
  background: var(--accent-06);
}
.ddpanel summary:hover { background: var(--accent-12); }
.ddpanel summary:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.ddwhen { font-weight: 600; color: var(--plum); font-size: 0.875rem; }
.ddmonth { font-size: 0.7812rem; color: var(--pen); }
.ddsession { padding: 12px 16px 14px; border-top: 1px solid var(--soft); }
.ddsession b { display: block; font-size: 0.9375rem; color: var(--ink); }
.ddmeta { font-size: 0.8125rem; color: var(--ink-60); margin-top: 3px; }
.ddlinks { display: flex; gap: 16px; flex-wrap: wrap; margin-top: 9px; }
.ddlinks a { font-size: 0.8125rem; font-weight: 500; }
/* A closed post-test still shows, so a missed window reads as closed rather
   than as a link that was never there. Not a link, so not styled as one. */
.ddclosed { font-size: 0.8125rem; color: var(--pen); }

/* The library and live-session tiles share the panels' grid so all four line
   up in one column width. The min-height matches a closed panel's summary bar,
   so the second row reads as a row rather than as two offcuts. */
.ddtiles { margin-top: 12px; }
.ddtiles .link { display: flex; flex-direction: column; justify-content: center; min-height: 66px; }

/* ---- Licensure (students and associates) ---- */

/* Three stacked fields and a file picker, sized so the whole thing fits one
   phone screen without scrolling past the button. The dates are the part with
   a deadline behind them; the file usually does not exist yet. */
.licform { display: flex; flex-direction: column; gap: 14px; align-items: flex-start; margin-top: 14px; }
.licform .caplabel { max-width: 340px; }
.licform input[type="date"] {
  font: inherit; font-size: 0.875rem; color: var(--ink);
  background: var(--paper); border: 1px solid var(--pen-12);
  border-radius: 10px; padding: 11px 12px; width: 100%;
}
.licform input[type="date"]:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.onfile { list-style: none; display: flex; flex-direction: column; gap: 0; margin-top: 10px; }
.onfile li { display: flex; justify-content: space-between; gap: 16px; padding: 9px 0; border-top: 1px solid var(--soft); font-size: 0.875rem; }
.onfile li:first-child { border-top: 0; }
.onfile span { color: var(--ink-60); }

/* ---- Announcements written in the hub (directors and leads) ---- */

.annedit { margin-top: 10px; font-size: 0.8125rem; }

/* A textarea rather than an input, because an announcement is sentences. It
   inherits the same treatment .caplabel gives its input and select so the three
   controls on this form read as one set. */
.annform { display: flex; flex-direction: column; gap: 14px; align-items: flex-start; margin-top: 14px; }
.annform .caplabel { max-width: 640px; width: 100%; }
/* The line under the box that says a dash makes a bullet. Quieter than the
   label above it, because it is a reminder and not the question. */
.annhint { font-size: 0.75rem; line-height: 1.45; color: var(--pen); }
.annform textarea {
  font: inherit; font-size: 0.875rem; color: var(--ink); resize: vertical;
  background: var(--paper); border: 1px solid var(--pen-12);
  border-radius: 10px; padding: 11px 12px; width: 100%;
}
.annform textarea:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.annlist { list-style: none; display: flex; flex-direction: column; gap: 0; margin-top: 10px; }
.annrow {
  display: flex; align-items: flex-start; gap: 14px; flex-wrap: wrap;
  padding: 12px 0; border-top: 1px solid var(--soft);
}
.annrow:first-child { border-top: 0; }
.annwho { flex: 1 1 260px; min-width: 0; }
.annbody { font-size: 0.9062rem; color: var(--ink); }
.annmeta { display: block; margin-top: 4px; font-size: 0.7812rem; color: var(--pen); }
/* Matches the 46px hit area the rest of the app settled on after 24px controls
   proved too small on a phone. */
.anndel button { min-height: 46px; }
/* A row open for editing gives its form the whole width instead of the
   name-then-pill-then-buttons layout the read-only rows use. */
.annrow.editing { display: block; }
.annrow.editing .annform { margin-top: 0; }
.annedits { display: flex; align-items: center; gap: 16px; }

/* ---- Trend charts (My Numbers) ---- */

/* Inline SVG drawn on the server. Every coordinate is an ATTRIBUTE, never a
   style attribute, because this app's CSP is style-src 'self' with no
   'unsafe-inline' and would drop a style="" silently. Colour lives here. */
.chartwrap { margin-top: 12px; overflow-x: auto; }
.chart { display: block; width: 100%; height: auto; min-width: 320px; }
.chart .gridline { stroke: var(--soft); stroke-width: 1; }
.chart .axis { fill: var(--pen); font-family: 'Poppins', system-ui, sans-serif; font-size: 11px; }
.chart .series { fill: none; stroke-width: 2.5; stroke-linejoin: round; stroke-linecap: round; }
.chart .series.therapy { stroke: var(--accent); }
.chart .series.meds { stroke: var(--lilac); }
.chart .dot { stroke: var(--card); stroke-width: 1.5; }
.chart .dot.therapy { fill: var(--accent); }
.chart .dot.meds { fill: var(--lilac); }
.chart .bar { fill: var(--accent); }

.chartkey { display: flex; gap: 14px; margin-top: 4px; font-size: 0.7812rem; color: var(--pen); }
.chartkey .key { display: inline-flex; align-items: center; gap: 6px; }
.chartkey .key::before { content: ""; width: 10px; height: 10px; border-radius: 3px; }
.chartkey .key.therapy::before { background: var(--accent); }
.chartkey .key.meds::before { background: var(--lilac); }

/* Jump back in: the row stretches to the full content width however many tiles
   the signed-in person gets. `.links` uses auto-FILL, which keeps ~200px tracks
   and left a third of the row empty when there were only three tiles; auto-FIT
   collapses the empty tracks so the ones that exist share the width.
   Scoped to this row on purpose — a one-tile group elsewhere would otherwise
   stretch a single button across the whole page. */
.links.jump { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }

/* ---- Home: Who to ask beside the Leadership box ---- */

/* The pair share the row so the half-width Who to ask card has something
   next to it rather than a gap. Alone (anyone not in leadership) it keeps the
   52% max-width rule above and this class never renders. */
.asrow { display: flex; flex-wrap: wrap; gap: 16px; align-items: stretch; margin-top: 20px; }
.asrow > * { flex: 1 1 300px; }
.asrow .ask { max-width: none; margin-top: 0; }

.leadcard {
  display: flex; flex-direction: column; justify-content: center;
  text-decoration: none; color: inherit;
  border: 1px solid var(--accent-12); background: var(--accent-06);
}
.leadcard:hover { border-color: var(--accent); }
.leadcard h3 { color: var(--plum); }
.leadgo {
  margin-top: 12px; align-self: flex-start;
  font-size: 0.8125rem; font-weight: 500;
  color: var(--paper); background: var(--accent);
  border-radius: 999px; padding: 8px 20px;
}
.leadcard:hover .leadgo { background: var(--plum); }

/* Numeric columns centre, text columns stay left. A column of figures read
   against a left edge makes 3 and 14 and 148 start in the same place and end
   in three different ones, which is the hardest shape to scan. Cassidy asked
   for centred rather than right-aligned. */
.numtable td, .numtable th { text-align: center; }
.numtable td:first-child, .numtable th:first-child { text-align: left; }

/* Figure tables sit at their natural width rather than stretching, so three
   columns do not end up a hand-span apart on a desktop. The last-child
   right-align from table.plain is overridden here: in a by-office table the
   last column is a figure like every other one, and it was the only one not
   centred. */
.numtable { width: auto; min-width: min(560px, 100%); }
/* table.plain's own `td { padding: 7px 0 }` is a type+class+type selector
   (0,1,2) — more specific than the plain `.numtable td` (0,1,1) above, so on
   any table combining both classes (every real use of .numtable does) that
   horizontal padding was silently never applying. Repeated here at
   table.plain.numtable's own specificity (0,2,2) to actually win. */
table.plain.numtable td, table.plain.numtable th { padding-left: 18px; padding-right: 18px; }
table.plain.numtable td:first-child, table.plain.numtable th:first-child { padding-left: 0; }
table.plain.numtable td:last-child { text-align: center; color: inherit; }
table.plain.numtable th:last-child { text-align: center; }

/* The one-line explainer under a page heading. `.sub` caps at 60ch so body copy
   stays readable, which breaks a short sentence that is meant to read as one
   line. */
.sub.oneline { max-width: none; }

/* The presenter under a session title on the catch-up page. Its own line so a
   long topic and a long name do not run together into one string. */
.hsby { display: block; font-size: 0.75rem; color: var(--pen); font-weight: 400; margin-top: 2px; }

/* ---- Website edits tracker ---- */

/* Same treatment .caplabel gives its input and select, so the page field, the
   issue box and the file button read as one set. Matches .annform's textarea
   rule rather than inventing a third look for the same control. */
.tweakform { display: flex; flex-direction: column; gap: 14px; align-items: flex-start; margin-top: 14px; }
.tweakform .caplabel { max-width: 640px; width: 100%; }
.tweakform textarea {
  font: inherit; font-size: 0.875rem; line-height: 1.5; color: var(--ink); resize: vertical;
  background: var(--paper); border: 1px solid var(--pen-12);
  border-radius: 10px; padding: 11px 12px; width: 100%;
}
.tweakform textarea:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* The page filters. A chip here is a LINK, not a status badge like the ones on
   My CE, so it takes the neutral tint and the current one fills in — a filter
   row where every chip looks equally chosen tells you nothing about which page
   you are looking at. */
.chip.filter {
  text-decoration: none; background: var(--accent-06); color: var(--accent);
  border: 1px solid transparent;
}
.chip.filter:hover { background: var(--accent-12); }
.chip.filter b { font-weight: 600; margin-left: 3px; }
.chip.filter.on { background: var(--accent); color: var(--paper); }

/* A tweak row is a paragraph plus a control, where a document row is a label
   plus a link — so it wraps and aligns to the top instead of centring on a
   thumbnail. On a phone the close control drops onto its own line rather than
   squeezing the sentence into a column three words wide. */
.taskrow { align-items: flex-start; flex-wrap: wrap; }
.taskissue { font-size: 0.875rem; line-height: 1.5; color: var(--ink); overflow-wrap: anywhere; }
.docwho .taskissue + span { margin-top: 4px; }

.taskclose { margin-left: auto; flex: none; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.taskclose input {
  font: inherit; font-size: 0.8125rem; color: var(--ink); width: 200px;
  border: 1px solid var(--soft); border-radius: 999px; padding: 8px 14px; background: var(--paper);
}
.taskclose input:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.taskclose button.primary { font-size: 0.8125rem; padding: 8px 18px; }

/* Where a website edit stands in review. A line under the request rather than
   a pill, because approved-with-changes carries the changes themselves. */
.taskstate { font-size: 0.8125rem; line-height: 1.5; margin-top: 6px; color: var(--pen); overflow-wrap: anywhere; }
.taskstate.approved b { color: var(--good); }
.taskstate.changes b { color: var(--warn); }
.taskstate.waiting { font-style: italic; }
.taskclose select {
  font: inherit; font-size: 0.8125rem; color: var(--ink); width: 210px;
  border: 1px solid var(--soft); border-radius: 999px; padding: 8px 14px; background: var(--paper);
}
.taskclose select:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* Ticking several rows for one status. The bar sits at the bottom of a section;
   the box leads each row so a column of them reads as a column. The bar
   closes each section that has more than one request. */
.taskbulk { margin: 14px 0 0; padding-top: 14px; border-top: 1px solid var(--soft); justify-content: flex-end; }
.tasktick { flex: none; width: 18px; height: 18px; margin-top: 3px; accent-color: var(--accent); cursor: pointer; }

/* The done list. Collapsed, and the summary carries the count so it says how
   much is behind it without being opened. */
.donebox summary {
  cursor: pointer; font-family: 'Playfair Display', Georgia, serif;
  font-size: 1.0625rem; color: var(--plum);
}
.donebox summary::marker { color: var(--pen); }
.donebox .doclist { margin-top: 12px; }

@media (max-width: 640px) {
  .taskclose { margin-left: 0; width: 100%; }
  .taskclose input { flex: 1; width: auto; min-width: 140px; }
  .taskclose select { flex: 1; width: auto; }
}

/* ---- My Matchmaker Profile ---- */

/* The textareas here were falling back to the browser's monospace default:
   .caplabel styles input and select, and the tweak form styles its own
   textarea, but this form is .mmform and matched neither. Same treatment as
   .annform and .noteform so every multi-line box in the app reads alike. */
.mmform { display: flex; flex-direction: column; gap: 14px; align-items: flex-start; margin-top: 14px; }
.mmform .caplabel { max-width: 640px; width: 100%; }
.mmform textarea {
  font: inherit; font-size: 0.875rem; line-height: 1.5; color: var(--ink); resize: vertical;
  background: var(--paper); border: 1px solid var(--pen-12);
  border-radius: 10px; padding: 11px 12px; width: 100%;
}
.mmform textarea:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.mmhint { display: block; font-size: 0.7188rem; color: var(--pen); margin-top: 2px; }

/* "Who you see" — the five accepts flags and the two age numbers, boxed
   together because they answer one question between them. A fieldset rather
   than a div so the legend is a real caption for the group in a screen reader,
   which a floating heading would not be. */
.mmgroup {
  border: 1px solid var(--soft); border-radius: 12px;
  padding: 14px 16px 16px; width: 100%; max-width: 640px;
}
.mmgroup legend { font-size: 0.8125rem; color: var(--pen); padding: 0 6px; }
.mmbools { display: flex; flex-wrap: wrap; gap: 10px 22px; }
/* The confirmation checkbox this borrows from is a full paragraph of promise on
   the photo wall; here each one is a single word, so it should not be forced to
   a 480px column. */
.mmcheck { max-width: none; width: auto; align-items: center; }
.mmages { display: flex; flex-wrap: wrap; gap: 14px 20px; margin-top: 14px; }
.mmnum { max-width: 220px; }

/* The current bio and the current avoids, shown above the box that suggests a
   change to them. Tinted so it reads as "this is what is live", distinct from
   the editable fields above it. */
.mmsuggest { margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--soft); }
.mmsuggest:first-of-type { border-top: 0; padding-top: 0; }
.mmsuggest h4 { font-size: 0.9375rem; color: var(--plum); }
.mmcurrent {
  margin-top: 6px; padding: 12px 14px; border-radius: 10px;
  background: var(--accent-06); font-size: 0.875rem; line-height: 1.55; color: var(--ink);
}
.mmcurrent i { color: var(--pen); }

/* The modality grid: 23 rows, four radio columns. Row headers left-aligned like
   a list; the radio cells centred under their level. On a phone the table
   scrolls inside its wrapper (.tablescroll) rather than widening the page. */
.mmgridwrap { width: 100%; }
.mmgrid { width: 100%; border-collapse: collapse; }
.mmgrid thead th {
  font-size: 0.7188rem; font-weight: 600; color: var(--pen);
  text-transform: uppercase; letter-spacing: .05em;
  text-align: center; padding: 0 10px 8px; white-space: nowrap;
}
.mmgrid thead th:first-child { text-align: left; padding-left: 0; }
.mmgrid tbody th {
  text-align: left; font-weight: 500; font-size: 0.875rem; color: var(--ink);
  padding: 9px 12px 9px 0; border-top: 1px solid var(--soft); white-space: nowrap;
}
.mmgrid tbody td { text-align: center; border-top: 1px solid var(--soft); padding: 9px 10px; }
.mmcell { display: inline-flex; cursor: pointer; }
.mmcell input { width: 17px; height: 17px; accent-color: var(--accent); cursor: pointer; }
/* The per-cell level text exists for screen readers and the narrow layout;
   on a desktop the column header already says it. */
.mmcelltext { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }

/* The skill/comfort grids. Same table skeleton as the modality grid; the cells
   hold selects instead of radios because each row answers on two axes. */
.mmsubhead { margin-top: 6px; font-size: 0.9375rem; color: var(--plum); }
.mmskills { width: 100%; border-collapse: collapse; }
.mmskills thead th {
  font-size: 0.7188rem; font-weight: 600; color: var(--pen);
  text-transform: uppercase; letter-spacing: .05em;
  text-align: left; padding: 0 12px 8px 0;
}
.mmskills tbody th {
  text-align: left; font-weight: 500; font-size: 0.875rem; color: var(--ink);
  padding: 8px 14px 8px 0; border-top: 1px solid var(--soft);
}
.mmskills tbody td { border-top: 1px solid var(--soft); padding: 8px 14px 8px 0; }
.mmskills select {
  font: inherit; font-size: 0.8125rem; color: var(--ink);
  border: 1px solid var(--soft); border-radius: 8px; padding: 6px 8px; background: var(--paper);
  max-width: 100%;
}
.mmskills select:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* Review queue rows: the was -> wants line and the action pair. */
.rvarrow { color: var(--pen); padding: 0 4px; }
.rvactions { margin-left: auto; flex: none; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.rvactions button.primary { font-size: 0.8125rem; padding: 8px 18px; }

/* The live matchmaker hero card: tinted so it reads as "this is the output",
   distinct from the editing cards below it. */
.mmhero { background: var(--accent-06); border: 1px solid var(--accent-12); }
.mmhero h3 { font-size: 1.25rem; }
.mmherolicense { font-size: 0.8125rem; color: var(--pen); font-weight: 400; margin-left: 6px; }
.mmherorow { margin-top: 12px; display: flex; align-items: center; flex-wrap: wrap; gap: 6px; }
.mmherorow b, .mmheroline b {
  font-size: 0.7188rem; font-weight: 600; color: var(--pen);
  text-transform: uppercase; letter-spacing: .05em; margin-right: 4px; flex: none;
}
.mmheroline { margin-top: 10px; font-size: 0.875rem; line-height: 1.5; }
.mmherolimit { display: block; margin-top: 4px; font-size: 0.7188rem; color: var(--pen); }
.mmpending { border-left: 3px solid var(--warn); }

/* Favorites: a small warm chip on the hero, and unobtrusive hearts in grids. */
.chip.mmfav { background: var(--warn-bg); color: var(--warn); }
.mmoffcell label[hidden] { display: none; }

/* The clientele nuance box. It inherited a default-width text input, which at
   table size holds about three words of the sentence it exists for — "only 10
   and up when I have seen the family before" needs room to be typed and read. */
.mmskills input[type=text] {
  font: inherit; font-size: 0.8125rem; color: var(--ink);
  border: 1px solid var(--soft); border-radius: 8px; padding: 7px 10px;
  background: var(--paper); width: 100%; min-width: 260px;
}
.mmskills input[type=text]:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* Favorite checkboxes centre under their header like the modality radios do.
   .mmskills cells are left-aligned for the selects; the fav cell is the
   exception, so it carries its own rule. */
.mmskills td:last-child { text-align: center; }
.mmskills td:last-child .mmcell { justify-content: center; }

/* The per-person approve-all press on the review queue. */
.rvall { margin: 10px 0 4px; }

/* The open-somebody's-profile picker for directors, leads and supervisors. */
.mmpicker { display: flex; align-items: flex-end; gap: 10px; margin-top: 10px; }
.mmpicker .caplabel { max-width: 320px; }
.mmpicker select {
  font: inherit; font-size: 0.875rem; color: var(--ink);
  border: 1px solid var(--soft); border-radius: 10px; padding: 9px 12px; background: var(--paper);
}

/* --- Credentialing ------------------------------------------------------- */
/* Harleigh's working screen. Every rule here is a class because the app's CSP
   is style-src 'self' with no 'unsafe-inline': an inline style attribute is
   dropped silently by the browser, with no error anywhere. */

/* The payer table carries five columns of quite different weight, so the note
   column is allowed to take the slack and the rest stay tight. */
table.plain.cred th {
  text-align: left; font-size: 0.75rem; font-weight: 600; color: var(--accent);
  padding: 0 12px 6px 0; border-bottom: 1px solid var(--soft);
}
table.plain.cred td { padding: 5px 12px 5px 0; vertical-align: top; }
table.plain.cred td:last-child { padding-right: 0; }
table.plain.cred .credpayer { font-weight: 600; color: var(--ink); }
table.plain.cred .credbilling,
table.plain.cred .creddates { color: var(--ink-60); white-space: nowrap; }
table.plain.cred .crednote { min-width: 22ch; }

/* The chip and any flag pills share a row and must not collide when a payer is
   both approved and carrying a chase date. */
table.plain.cred .chip { margin-right: 6px; }
table.plain.cred .pill { margin-right: 6px; }

/* Checkbox and payer name read as one target, so ticking is a click on the
   name rather than on a 13px box. */
.credpick { display: inline-flex; align-items: baseline; gap: 8px; cursor: pointer; }
.credpick input { margin: 0; }

.credwhen { display: block; font-size: 0.75rem; color: var(--pen); }
.credbody { display: block; margin-top: 1px; white-space: pre-line; line-height: 1.45; }
.credmuted { color: var(--pen); }

/* The controls under each provider's table. auto-fill keeps a field about the
   same width whether the row holds two or five, the same reasoning as .links. */
.credcontrols {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 10px; margin-top: 12px;
}
.credcontrols .caplabel { max-width: none; }
.credcontrols .credwide { grid-column: 1 / -1; }
.credcontrols select,
.credcontrols textarea {
  font: inherit; color: var(--ink); background: var(--card);
  border: 1px solid var(--pen-12); border-radius: 10px; padding: 9px 11px; width: 100%;
}
.credcontrols textarea { resize: vertical; min-height: 44px; }
.credcontrols select:focus-visible,
.credcontrols textarea:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.credform .photonote { margin-top: 8px; }
.credform button.primary { margin-top: 10px; }

/* Secondary forms and the note history collapse by default: the page is long
   enough with one card per provider, and neither is needed to read the table. */
.credextra { margin-top: 12px; border-top: 1px solid var(--soft); padding-top: 10px; }
.credextra summary {
  cursor: pointer; font-size: 0.8438rem; font-weight: 600; color: var(--accent);
}
.credextra summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.credhistory { list-style: none; margin-top: 12px; }
.credhistory li { padding: 7px 0; border-top: 1px solid var(--soft); font-size: 0.8438rem; }
.credhistory li:first-child { border-top: 0; }

/* The jump list. A wrapping row of name chips rather than a column: eleven
   providers fit in two lines, so the whole roster is visible without the list
   itself becoming something to scroll past. */
.credjumprow { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 10px; }
.credjump {
  display: inline-flex; align-items: baseline; gap: 7px;
  font-size: 0.8125rem; font-weight: 500; text-decoration: none;
  color: var(--plum); background: var(--accent-06);
  border: 1px solid transparent; border-radius: 999px; padding: 6px 13px;
}
.credjump:hover, .credjump:focus-visible { border-color: var(--accent); }
.credjumpn { font-size: 0.75rem; color: var(--pen); }

/* An anchored card lands flush against the sticky header without this. */
.credprovider { scroll-margin-top: 18px; }

/* "No credentialing needed" is longer than a stage name and must not be forced
   onto two lines inside the table cell. */
.chip.credresting { white-space: nowrap; font-weight: 500; }

/* Each provider's share of their own credentialing, done at a glance. The bar
   is a real <progress>: its width comes from value/max attributes, which is the
   only way to draw a proportional bar under a CSP that drops inline styles. */
.credprogress { display: flex; align-items: center; gap: 10px; }
.credbar {
  appearance: none; -webkit-appearance: none;
  width: 150px; height: 7px; border: 0; border-radius: 999px;
  background: var(--pen-12); color: var(--accent);
}
.credbar::-webkit-progress-bar { background: var(--pen-12); border-radius: 999px; }
.credbar::-webkit-progress-value { background: var(--accent); border-radius: 999px; }
.credbar::-moz-progress-bar { background: var(--accent); border-radius: 999px; }
.credpct { font-size: 0.8438rem; color: var(--plum); }
.credphrase { font-size: 0.8125rem; color: var(--ink-60); }

/* The provider cards stack, so the gap between them carries the whole page's
   sense of length. */
.credprovider { margin-top: 12px; }
.credprovider h3 { margin-bottom: 4px; }
.credprovider .own { margin-bottom: 6px; }

/* Six tally cards, laid out three and three rather than the global four-up.
   Four columns split them 4 + 2, which orphans the last row; three columns give
   two even rows of three. Scoped to this page's strip so no other .cards grid
   is touched. */
.credtally { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 900px) { .credtally { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 520px) { .credtally { grid-template-columns: 1fr; } }

/* Name on the left, progress in the top right corner. It wraps rather than
   squeezing on a narrow window, which keeps the bar at a readable width instead
   of shrinking it to a sliver. */
.credhead {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
}
.credhead h3 { margin-bottom: 0; }

/* The break between the summary half of the page (tally, jump list) and the
   per-provider half. Without it the jump card and the first provider card read
   as one run of cards. */
.credbreak {
  border: 0; border-top: 1px solid var(--pen-12);
  margin: 26px 0 4px;
}

/* A prefilled answer says where it came from, under the box it filled. */
.credhint { font-size: 0.75rem; color: var(--pen); line-height: 1.4; }

/* Harleigh's read of what a provider sent in. */
.credintake { margin-top: 10px; }
.credfiles { list-style: none; display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; }
.credfiles li { display: inline-flex; align-items: baseline; gap: 6px; }
.credintake .credhistory li:first-child { border-top: 1px solid var(--soft); }

/* The three credentialing figures on My Profile. Smaller than the metric cards
   on a page of their own: this is a summary inside a card, not the page's
   headline, and it sits beside the photo and paperwork cards. */
.credmini { display: flex; flex-wrap: wrap; gap: 22px; margin-top: 12px; }
.credminifig { display: flex; flex-direction: column; gap: 1px; }
.credminifig b {
  font-family: 'Playfair Display', serif; font-size: 1.625rem;
  line-height: 1.1; color: var(--plum); font-weight: 600;
}
.credminifig span { font-size: 0.75rem; font-weight: 600; color: var(--accent); }

/* The provider's own strip is three across at every width above a phone: three
   figures, one row, no orphan. */
.credtally.credmine { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 1000px) { .credtally.credmine { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 520px) { .credtally.credmine { grid-template-columns: 1fr; } }

/* Muted detail that belongs ON the same line as what it describes. .credwhen is
   a block because a note's date sits ABOVE the note; a document's description
   sits beside its name, and forcing a break there turned a four-row table into
   an eight-line one. */
.credmeta { font-size: 0.75rem; color: var(--pen); }

/* The invite button and, once it has gone, the date it went. Inline so the two
   read as one statement rather than a button with an orphaned line under it. */
.credinvite { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; margin-bottom: 12px; }
.credinvite button.primary { margin-top: 0; }

/* A group heading inside a form: "License", then "Malpractice insurance". Small
   and coloured like a label rather than a card heading, so the card still reads
   as one thing. */
.credgroup {
  font-size: 0.8125rem; font-weight: 600; color: var(--accent);
  margin: 16px 0 0;
}
.credform .credgroup:first-of-type { margin-top: 12px; }

/* ---- Billing requests ---- */
/* The form is a single column: one question at a time is right for a request
   somebody types on a phone between sessions, and the kind picker hides the
   fields that do not apply, so there is nothing to lay out side by side. */
.billform { display: flex; flex-direction: column; gap: 14px; margin-top: 12px; }
.billform .caplabel { max-width: 560px; }
.billform .caplabel textarea {
  font: inherit; font-size: 0.875rem; padding: 9px 12px; border: 1px solid var(--soft);
  border-radius: 10px; background: var(--paper); color: var(--ink); resize: vertical; min-height: 88px;
}
.billform .caplabel textarea:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.billform .caplabel input[type="date"] { max-width: 220px; }
.billhint { font-size: 0.8125rem; color: var(--ink-60); line-height: 1.5; max-width: 560px; }
.billhint b { color: var(--plum); font-weight: 500; }
.billform button.primary { align-self: flex-start; margin-top: 4px; }
.billerr { color: var(--warn); font-size: 0.8125rem; }

/* The provider's own list under the form. Status on the right so a glance
   down the column answers "did anyone get it" for every request at once. */
.reqrow .pill { margin: 0; white-space: nowrap; flex: none; }
.reqrow .reqnote { font-size: 0.8125rem; color: var(--ink); margin-top: 4px; white-space: pre-line; }
.pill.claimed { background: var(--accent-06); color: var(--accent); }
.pill.open { background: var(--pen-12); color: var(--pen); }
/* The kind picker hides fields with the hidden attribute, and .caplabel's
   display:flex would otherwise beat the browser's own [hidden] rule and keep
   them on screen. This is the one place that attribute has to win. */
.billform [hidden] { display: none !important; }

/* ---- Billing queue ---- */
/* Three counts, three columns: open by owner, waiting by party, done this
   week. The per-name lines sit under the big number so the card answers
   "how many" and "whose" in one glance. */
.billcounts { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 900px) { .billcounts { grid-template-columns: 1fr; } }
.billlines { margin-top: 8px; display: flex; flex-direction: column; gap: 3px; }
.billline { display: flex; justify-content: space-between; font-size: 0.8125rem; color: var(--ink-60); }
.billline b { color: var(--plum); font-weight: 600; }
.billfilters { margin-top: 8px; }

/* A ticket is a collapsed card: the summary line is the whole row on the
   board, and opening it shows the detail, the actions and the history. */
.billticket summary {
  cursor: pointer; display: flex; align-items: center; gap: 12px; list-style: none;
}
.billticket summary::-webkit-details-marker { display: none; }
.billsum { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.billsum b { font-weight: 500; color: var(--ink); }
.billsum span { font-size: 0.7812rem; color: var(--pen); }
.billticket .pill { margin: 0; flex: none; white-space: nowrap; }
.billdetail { margin-top: 12px; font-size: 0.875rem; color: var(--ink); line-height: 1.5; overflow-wrap: anywhere; }
.billdetail a { color: var(--accent); }
.billsum a.billclient { color: var(--accent); text-decoration: underline; }
.billdetail b { font-weight: 600; color: var(--plum); }

/* The four actions, each its own small form, laid out side by side where
   there is room. Resolve is separated so it reads as the way out, not one
   more control. */
.billactions {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 14px; margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--soft);
}
.billaction { display: flex; flex-direction: column; gap: 8px; align-items: flex-start; }
.billaction .caplabel { max-width: none; }
.billaction button.primary { font-size: 0.8125rem; padding: 8px 18px; }
.billresolve { grid-column: 1 / -1; border-top: 1px dashed var(--pen-12); padding-top: 12px; }
.billticket .credhistory { margin-top: 14px; }
/* The current state of an open ticket: what it is waiting for and the last
   note, boxed so it reads as "where this stands" and not one more paragraph. */
.billstate { background: var(--accent-06); border-radius: 8px; padding: 10px 12px; }
/* The way into the drop folder, a button-shaped link above the instructions
   so it reads as the first step rather than a word in a sentence. */
.billdrop {
  display: inline-block; margin-bottom: 6px; font-weight: 500; text-decoration: none;
  color: var(--paper); background: var(--accent); border-radius: 999px; padding: 6px 14px;
}
.billdrop:hover { background: var(--plum); }

/* ---- Records requests ---- */
.billradios, .billchecks { border: 0; display: flex; flex-wrap: wrap; gap: 8px 18px; max-width: 560px; }
.billradios legend, .billchecks legend { font-size: 0.8125rem; color: var(--ink-60); margin-bottom: 6px; }
.billradios .credpick, .billchecks .credpick { font-size: 0.875rem; color: var(--ink); }
.billpair { display: flex; gap: 14px; flex-wrap: wrap; }
.billpair .caplabel { max-width: 220px; }
.reccounts { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 1000px) { .reccounts { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 520px) { .reccounts { grid-template-columns: 1fr; } }
.metric.overdue .num { color: var(--warn); }
.chip.prio { font-size: 0.75rem; padding: 2px 9px; }
.chip.prio.urgent { background: var(--warn-bg); color: var(--warn); }
.chip.prio.standard { background: var(--accent-06); color: var(--accent); }
.chip.prio.low { background: var(--pen-12); color: var(--pen); }
.billover { color: var(--warn); font-weight: 600; }
.billticket.overdue { border-left: 3px solid var(--warn); }
.billfacts { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 6px 18px; margin-top: 12px; }
.billfacts div { display: flex; flex-direction: column; font-size: 0.8125rem; }
.billfacts span { color: var(--pen); font-size: 0.75rem; }
.billfacts b { font-weight: 500; color: var(--ink); overflow-wrap: anywhere; }

/* The letter. A plain sheet, and everything that is not the letter is hidden
   when printing. The two PHI inputs print as the typed text with no box. */
.letterbody { background: var(--paper); color: var(--ink); font-family: 'Poppins', system-ui, sans-serif; margin: 0; }
.letterbar {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap; padding: 12px 20px;
  background: var(--card); border-bottom: 1px solid var(--soft); font-size: 0.8125rem; color: var(--ink-60);
}
.letterbar a { color: var(--accent); }
.letterbar form { margin: 0; }
.letterbar button.primary { font-size: 0.8125rem; padding: 8px 16px; }
.letter { max-width: 720px; margin: 28px auto; background: #fff; padding: 48px 56px; line-height: 1.55; font-size: 0.9375rem; }
.letter p, .letter ul { margin: 0 0 14px; }
.letter ul { padding-left: 22px; }
.letterhead { display: flex; justify-content: space-between; align-items: flex-end; gap: 20px; margin-bottom: 28px; font-size: 0.8125rem; color: var(--ink-60); text-align: right; }
.letterphi { display: flex; flex-direction: column; gap: 8px; margin: 0 0 16px; }
.letterphi label { display: flex; gap: 10px; align-items: baseline; }
.letterphi input { font: inherit; border: 0; border-bottom: 1px solid var(--ink); background: transparent; padding: 2px 4px; min-width: 280px; }
.lettersig { margin-top: 32px; }
.letterfoot { margin-top: 40px; font-size: 0.75rem; color: var(--pen); border-top: 1px solid var(--soft); padding-top: 8px; }
@media print {
  .letterbar { display: none; }
  .letterbody { background: #fff; }
  .letter { margin: 0; padding: 0; max-width: none; }
  .letterphi input { border-bottom: 0; }
}
/* Two halves of one paperwork card: the Drive-linked license and policy, then
   the credentialing uploads. The second heading sits inside the card. */
.docsub { margin-top: 22px; padding-top: 16px; border-top: 1px solid var(--soft); }
.doccard .billform { margin-top: 12px; margin-bottom: 4px; }


/* ---- CE Tracker (/ce) ----
   The screens Cassidy approved in the 2026-09-10 preview, on the hub's own
   tokens. Scoped under .cetracker so nothing here leaks into other pages. The
   type sits a step under the hub's body size: these are working screens with
   tables, and the hub's 23px desktop base put a seven-column table off the
   edge of a laptop. */
.cetracker { --ce-bad: #8E3B3B; --ce-bad-bg: rgba(142, 59, 59, 0.12); --ce-info: #3F5A8A; --ce-info-bg: rgba(63, 90, 138, 0.12); font-size: 0.82rem; }
.cetracker .cehead { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.cetracker .eyebrow { font-size: 0.66rem; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--pen); }
.cetracker .cehead h2 { font-size: 1.6rem; margin-top: 2px; color: var(--plum); }
.cetracker .cehead .sub { color: var(--ink-60); font-size: 0.82rem; margin-top: 4px; }
/* Two deliberate lines of about the same length, rather than one long line
   that broke wherever the width ran out. On a narrow screen each line still
   wraps, balanced, and never inside an approval number. */
.cetracker .cehead .sub .line { display: block; text-wrap: balance; }
.cetracker .cehead .sub .keep { white-space: nowrap; }
.cetracker .cesubnav { display: flex; gap: 4px; flex-wrap: wrap; margin-top: 16px; border-bottom: 1px solid var(--pen-12); }
.cetracker .cesubnav a { text-decoration: none; color: var(--ink-60); font-size: 0.82rem; font-weight: 500; padding: 9px 13px; border-bottom: 3px solid transparent; margin-bottom: -1px; display: inline-flex; align-items: center; gap: 8px; }
.cetracker .cesubnav a:hover { color: var(--plum); }
.cetracker .cesubnav a.on { color: var(--plum); border-bottom-color: var(--accent); }
.cetracker .cecount { font-size: 0.64rem; font-weight: 600; background: var(--warn-bg); color: var(--warn); border-radius: 999px; padding: 1px 8px; min-width: 22px; text-align: center; }
.cetracker .cecount.bad { background: var(--ce-bad-bg); color: var(--ce-bad); }
.cetracker .ceview { margin-top: 20px; }
.cetracker .pagehead { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; }
.cetracker .pagehead h3 { font-size: 1.25rem; color: var(--plum); }
.cetracker .pagehead .sub { font-size: 0.8rem; color: var(--ink-60); max-width: 70ch; margin-top: 2px; }
.cetracker .pagehead .actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.cetracker h3 { font-size: 1.05rem; color: var(--plum); }
.cetracker .card { padding: 16px 18px; }
.cetracker .card + .card, .cetracker .cards + .card, .cetracker .card + .cards, .cetracker .cards + .cards, .cetracker .cards + .two, .cetracker .card + .two, .cetracker .two + .card { margin-top: 14px; }
.cetracker .cards { margin-top: 0; gap: 12px; }
.cetracker .card .sub { font-size: 0.8rem; color: var(--ink-60); max-width: 70ch; margin-top: 2px; }
.cetracker .metric .label { font-size: 0.74rem; }
.cetracker .metric .num { font-size: 2rem; margin: 4px 0 0; font-variant-numeric: tabular-nums; }
.cetracker .metric .num small { font-family: 'Poppins', sans-serif; font-size: 0.78rem; color: var(--pen); font-weight: 400; margin-left: 4px; }
.cetracker .metric .expl { margin-top: 8px; padding-top: 8px; font-size: 0.74rem; }
/* A person's cycle totals: however many there are (hours, ethics, suicide
   prevention, asynchronous, presenting), one row of equal cards, sized down so
   five fit. The grid's 4 columns wrapped the fifth onto a line of its own. */
.cetracker .cards.cyclecards { grid-template-columns: none; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 10px; }
.cetracker .cards.cyclecards .metric { padding: 14px 14px 12px; }
.cetracker .cards.cyclecards .metric .num { font-size: 1.6rem; }
/* The status badge beside a person's name wraps rather than running off a phone. */
.cetracker .card .bar .pill { max-width: 100%; white-space: normal; }
@media (max-width: 760px) {
  .cetracker .cards.cyclecards { grid-auto-flow: row; grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.cetracker .metric.warn .num { color: var(--warn); }
.cetracker .metric.bad .num { color: var(--ce-bad); }
.cetracker .metric.good .num { color: var(--good); }
.cetracker .pill { margin-top: 0; font-size: 0.68rem; line-height: 1.5; padding: 3px 10px; white-space: nowrap; }
.cetracker .pill.bad { background: var(--ce-bad-bg); color: var(--ce-bad); }
.cetracker .pill.info { background: var(--ce-info-bg); color: var(--ce-info); }
.cetracker .pill.grey { background: var(--pen-12); color: var(--pen); }
.cetracker .pill.plum { background: var(--accent-12); color: var(--plum); }
.cetracker .tag { display: inline-block; font-size: 0.66rem; border-radius: 6px; padding: 1px 8px; background: var(--accent-06); color: var(--accent); margin: 2px 4px 2px 0; white-space: nowrap; }
.cetracker .notice { margin: 0 0 14px; font-size: 0.82rem; }
.cetracker .notice.good { background: var(--good-bg); border-color: rgba(76, 122, 92, 0.4); color: var(--good); }
.cetracker .notice.warn { background: var(--warn-bg); border-color: rgba(154, 107, 47, 0.4); color: var(--warn); }
.cetracker .notice.bad { background: var(--ce-bad-bg); border-color: rgba(142, 59, 59, 0.4); color: var(--ce-bad); font-weight: 500; }
.cetracker .notice.info { background: var(--ce-info-bg); border-color: rgba(63, 90, 138, 0.3); }
.cetracker .notice a { color: inherit; }
.cetracker .hint { font-size: 0.76rem; color: var(--pen); }
.cetracker .hint.pad { padding: 8px 0; }
.cetracker .warntext { color: var(--ce-bad); }
/* Tables */
.cetracker table.ce { width: 100%; border-collapse: collapse; font-size: 0.8rem; }
.cetracker table.ce th { text-align: left; font-size: 0.66rem; letter-spacing: 0.05em; text-transform: uppercase; color: var(--pen); font-weight: 600; padding: 8px 10px; border-bottom: 1px solid var(--pen-12); white-space: nowrap; }
.cetracker table.ce td { padding: 9px 10px; border-top: 1px solid var(--soft); vertical-align: top; }
.cetracker table.ce tr:first-child td { border-top: 0; }
.cetracker table.ce td .who { font-weight: 500; color: var(--ink); text-decoration: none; }
.cetracker table.ce td a.who:hover { text-decoration: underline; }
.cetracker table.ce td .sm { display: block; font-size: 0.7rem; color: var(--pen); }
.cetracker table.ce td.num { font-variant-numeric: tabular-nums; white-space: nowrap; }
/* Delivery and Hours on Trainings on file: short values under a short header,
   which read as a column only when both sit on the same center line. */
/* My CE: the jump link to the add form, the cycle chips, the certificate
   folders and the Utah rules links at the foot. */
.cetracker h3.grow { flex: 1; }
.myce-top { margin-bottom: 14px; }
.cyclechips { margin-top: 12px; }
#add-training,
#add-presentation { scroll-margin-top: 16px; }
.myce-top { gap: 8px; }
.presentlist { margin: 10px 0 0; padding: 0; list-style: none; }
.presentlist li { padding: 6px 0; border-top: 1px solid var(--soft); font-size: 0.875rem; }
.presentlist li:first-child { border-top: 0; }
.presentlist .when { display: inline-block; min-width: 88px; color: var(--pen); font-variant-numeric: tabular-nums; }
.presentlist .muted { color: var(--pen); }
#add-training h3 { margin-bottom: 4px; }
.certfolder { border-top: 1px solid var(--soft); padding: 10px 0 2px; }
.certfolder:first-of-type { border-top: 0; }
.certfolder > summary { cursor: pointer; font-weight: 500; color: var(--ink); width: fit-content; }
.certfolder > summary .muted { font-weight: 400; color: var(--pen); }
.certfolder > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
.certfolder .doclist { margin-top: 6px; }
.dopl ul { margin: 8px 0 0; padding-left: 18px; }
.dopl li { margin: 4px 0; }
.dopl a { color: var(--accent); }
.cetracker table.ce th.ctr,
.cetracker table.ce td.ctr { text-align: center; }
.cetracker table.ce tr.dim td { opacity: 0.6; }
.cetracker table.ce input { padding: 6px 8px; font-size: 0.8rem; }
.cetracker .meter { height: 6px; background: var(--soft); border-radius: 999px; overflow: hidden; margin-top: 5px; min-width: 80px; }
.cetracker .meter i { display: block; height: 100%; background: var(--accent); }
.cetracker .meter.ok i { background: var(--good); }
.cetracker .meter.short i { background: var(--warn); }
.cetracker .mlabel { font-size: 0.72rem; color: var(--ink-60); white-space: nowrap; font-variant-numeric: tabular-nums; }
/* Action list */
.cetracker .alist { display: flex; flex-direction: column; }
.cetracker .aitem { display: grid; grid-template-columns: auto 1fr auto; gap: 12px; align-items: center; padding: 10px 0; border-top: 1px solid var(--soft); }
.cetracker .aitem.two-col { grid-template-columns: 1fr auto; }
.cetracker .aitem:first-child { border-top: 0; }
.cetracker .aitem .what b { font-weight: 500; display: block; }
.cetracker .aitem .what .miss { font-size: 0.74rem; color: var(--ink-60); display: block; }
@media (max-width: 600px) { .cetracker .aitem { grid-template-columns: 1fr; gap: 6px; } }
/* Buttons and forms */
.cetracker .btn { padding: 8px 15px; font-size: 0.82rem; border-radius: 10px; }
.cetracker .btn.sm { padding: 6px 12px; font-size: 0.74rem; border-radius: 8px; }
.cetracker .btn.plain { background: transparent; border-color: transparent; color: var(--accent); padding-left: 4px; padding-right: 4px; }
.cetracker form.inline { display: inline; }
.cetracker .bar { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.cetracker .chips { gap: 8px; margin-top: 0; }
.cetracker .chip { font-size: 0.76rem; padding: 5px 13px; background: var(--accent-06); color: var(--accent); text-decoration: none; }
.cetracker .chip.on { background: var(--plum); color: #F7F1EE; }
.cetracker .grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 12px 16px; }
.cetracker .f { display: flex; flex-direction: column; gap: 4px; font-size: 0.76rem; color: var(--ink-60); }
.cetracker .f b { font-weight: 500; color: var(--ink); }
.cetracker .f .help { font-size: 0.7rem; color: var(--pen); }
.cetracker .full { grid-column: 1 / -1; }
.cetracker input, .cetracker select, .cetracker textarea { width: 100%; font: inherit; font-size: 0.84rem; padding: 8px 10px; border: 1px solid var(--pen-12); border-radius: 9px; background: #fff; color: var(--ink); }
.cetracker input[readonly] { background: var(--card); color: var(--pen); }
.cetracker input:focus-visible, .cetracker select:focus-visible, .cetracker textarea:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.cetracker textarea { min-height: 72px; resize: vertical; }
.cetracker input[type="search"] { width: auto; }
.cetracker input[type="checkbox"] { width: 15px; height: 15px; accent-color: var(--accent); padding: 0; }
.cetracker .checks { display: flex; flex-wrap: wrap; gap: 6px 18px; font-size: 0.8rem; color: var(--ink); }
.cetracker .checks label { display: inline-flex; align-items: center; gap: 6px; }
.cetracker .kv { display: grid; grid-template-columns: minmax(200px, 1fr) 2fr auto; gap: 10px; align-items: center; padding: 9px 0; border-top: 1px solid var(--soft); }
.cetracker form:first-child .kv { border-top: 0; }
.cetracker .kv .k { font-weight: 500; font-size: 0.82rem; }
.cetracker .kv .k .help { display: block; font-weight: 400; font-size: 0.7rem; color: var(--pen); }
.cetracker .kv.blank .k::after { content: " (blank)"; color: var(--warn); font-weight: 600; }
@media (max-width: 640px) { .cetracker .kv { grid-template-columns: 1fr; } }
.cetracker .stmtlabel { display: block; font-size: 0.78rem; margin-top: 8px; }
.cetracker .stmt { font-size: 0.78rem; background: var(--accent-06); border-radius: 10px; padding: 10px 14px; margin: 6px 0 10px; white-space: pre-wrap; line-height: 1.5; }
/* Stages on the training page */
.cetracker .stage { background: var(--card); border: 1px solid var(--pen-12); border-radius: 16px; padding: 14px 18px; border-left: 4px solid var(--lilac); }
.cetracker .stage.ok { border-left-color: var(--good); }
.cetracker .stage.todo { border-left-color: var(--warn); }
.cetracker .stage.later { border-left-color: var(--ce-info); }
.cetracker .stage + .stage, .cetracker .stage + .card, .cetracker .pagehead + .stage { margin-top: 14px; }
.cetracker .stage .shead { display: flex; align-items: center; gap: 10px; margin-bottom: 4px; }
.cetracker .stage .shead h3 { flex: 1; }
.cetracker .evrow { display: grid; grid-template-columns: 76px 1fr auto; gap: 12px; align-items: center; padding: 9px 0; border-top: 1px solid var(--soft); }
.cetracker .evrow:first-of-type { border-top: 0; }
.cetracker .evrow .lab { font-weight: 500; }
.cetracker .evrow .det { font-size: 0.74rem; color: var(--ink-60); }
.cetracker .evrow .act { display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
@media (max-width: 640px) { .cetracker .evrow { grid-template-columns: 76px 1fr; } .cetracker .evrow .act { grid-column: 1 / -1; justify-content: flex-start; } }
.cetracker .drop { border: 2px dashed var(--pen-12); border-radius: 12px; padding: 16px; text-align: center; background: var(--accent-06); font-size: 0.8rem; color: var(--ink-60); margin-top: 10px; }
.cetracker .drop b { color: var(--plum); }
.cetracker .drop.over { border-color: var(--accent); background: var(--accent-12); }
.cetracker .drop .linklike { color: var(--accent); text-decoration: underline; cursor: pointer; }
.cetracker .doc { display: flex; align-items: baseline; gap: 8px; padding: 7px 0; border-top: 1px solid var(--soft); font-size: 0.8rem; }
.cetracker .doc:first-of-type { border-top: 0; }
.cetracker .doc .when { margin-left: auto; font-size: 0.7rem; color: var(--pen); white-space: nowrap; }
.cetracker .two { display: grid; grid-template-columns: 1.4fr 1fr; gap: 14px; align-items: start; }
@media (max-width: 800px) { .cetracker .two { grid-template-columns: 1fr; } }
.cetracker .two > .card { margin-top: 0; }

/* Collections: the week-by-week table has eight columns and a notes column,
   so it scrolls sideways on a phone rather than squeezing the page. */
.tablewrap { overflow-x: auto; }
.tablewrap table.plain.numtable td:last-child,
.tablewrap table.plain.numtable th:last-child { text-align: left; min-width: 22ch; }
.tablewrap table.plain.numtable th { font-size: 0.7812rem; color: var(--pen); font-weight: 600; padding-bottom: 6px; }

/* CE Tracker: a live training's sign-in and attendance page (pages/ce-liveday.js). */
.cetracker .ld-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); gap: 10px; margin: 0 0 14px; }
.cetracker .ld-card { background: #fff; border: 1px solid var(--pen-12); border-radius: 10px; padding: 10px 12px; }
.cetracker .ld-num { font-size: 1.5rem; font-weight: 600; color: var(--plum); }
.cetracker .ld-gap { margin-top: 10px; }
.cetracker .ld-short { width: 120px; }
.cetracker .ld-signin { margin-top: 12px; }

/* Who is out, on the billing queue */
.billaway summary { cursor: pointer; display: flex; gap: 0.5rem; align-items: center; }
.billaway .billlines { margin: 0.6rem 0; }
.billaway form.inline { display: inline; margin-left: 0.5rem; }
.billaway .checkline { display: flex; gap: 0.4rem; align-items: center; font-size: 0.85rem; }
.billaway form.inline button.primary { font-size: 0.75rem; padding: 4px 14px; }

/* live training: the after-the-training checklist */
.cetracker .ld-tiny { width: 70px; }
.cetracker .ld-step { display: flex; gap: 12px; padding: 12px 0; border-top: 1px solid var(--soft); }
.cetracker .ld-step:first-of-type { border-top: 0; }
.cetracker .ld-stepn { flex: 0 0 28px; height: 28px; border-radius: 999px; background: var(--pen-12); display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 0.85rem; }
.cetracker .ld-step.done .ld-stepn { background: var(--good-bg); color: var(--good); }
.cetracker .ld-stepbody { flex: 1; min-width: 0; }

/* ---- Answers: Q&A, policies and SOPs ---- */

/* One search box, the same on Answers, Home and Policies. */
.kbsearch { display: flex; gap: 8px; flex-wrap: wrap; margin: 12px 0 4px; max-width: 820px; }
.kbsearch input[type="search"] {
  flex: 1 1 240px; font: inherit; font-size: 0.9375rem; color: var(--ink);
  border: 2px solid var(--accent); border-radius: 999px; padding: 11px 18px; background: #fff;
  box-shadow: 0 1px 4px rgba(74, 33, 81, 0.12);
}
.kbsearch input[type="search"]::placeholder { color: var(--pen); }
.kbsearch input[type="search"]:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.homesearch { margin: 10px 0 4px; }
.homesearch .kbsearch { max-width: none; margin: 0; }
.askthen { margin: 12px 0 2px; }
.kbadd { margin: 12px 0; }
.kblist { list-style: none; margin: 8px 0 0; padding: 0; }
.kbrow { padding: 12px 0; border-top: 1px solid var(--soft); }
.kbrow:first-child { border-top: 0; }
.kbrow a b { color: var(--plum); }
.kbrow p { font-size: 0.875rem; line-height: 1.55; color: var(--ink); margin-top: 4px; overflow-wrap: anywhere; }
.kbrow mark { background: var(--accent-12); color: inherit; border-radius: 3px; padding: 0 2px; }
.kbmeta { display: block; font-size: 0.75rem; color: var(--pen); margin-top: 2px; }
.kbbody { font-size: 0.9375rem; line-height: 1.65; color: var(--ink); margin-top: 10px; overflow-wrap: anywhere; }
.kbwarn { font-size: 0.8125rem; color: var(--warn); }

/* Paid holidays on Policies & Onboarding. Past ones are dimmed, not removed. */
.holidays { list-style: none; margin: 10px 0 0; padding: 0; max-width: 560px; }
.holiday { display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; padding: 9px 0; border-top: 1px solid var(--soft); font-size: 0.875rem; color: var(--ink); }
.holiday:first-child { border-top: 0; }
.holiday span { color: var(--pen); }
.holiday.past { opacity: 0.5; }

/* Policies & Onboarding as a table of contents: every section a <details>
   card that opens in place. The summary carries the title and a one-line
   blurb so a closed section still says what is inside. */
.polsection { scroll-margin-top: 16px; }
.polsection > summary { cursor: pointer; list-style: none; display: flex; flex-direction: column; gap: 2px; position: relative; padding-right: 28px; }
.polsection > summary::-webkit-details-marker { display: none; }
.polsection > summary::after {
  content: '+'; position: absolute; right: 0; top: 0; font-size: 1.25rem; line-height: 1; color: var(--accent);
}
.polsection[open] > summary::after { content: '\2212'; }
.polsection > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; border-radius: 6px; }
.poltitle { font-family: 'Playfair Display', Georgia, serif; font-size: 1.125rem; color: var(--plum); }
.polblurb { font-size: 0.7812rem; color: var(--pen); }
.polbody { margin-top: 14px; }
.polsub { font-size: 0.9375rem; color: var(--plum); margin-top: 18px; }
.polhint { margin-top: 14px; }
.pollinks { list-style: none; margin: 6px 0 0; padding: 0; }
.pollinks li { padding: 7px 0; border-top: 1px solid var(--soft); font-size: 0.875rem; }
.pollinks li:first-child { border-top: 0; }
.pollinks a { color: var(--ink); text-decoration: none; }
.pollinks a:hover { color: var(--accent); text-decoration: underline; }
.polquick a { color: var(--accent); font-weight: 500; }
.polnum { display: inline-block; min-width: 2.6em; color: var(--pen); font-variant-numeric: tabular-nums; }
.polchapter { border-top: 1px solid var(--soft); padding: 10px 0; }
.polchapter > summary { cursor: pointer; font-size: 0.9375rem; color: var(--ink); font-weight: 500; }
.polchapter > summary::marker { color: var(--pen); }
.polchapter .pollinks { margin-left: 18px; }
/* The announcement composer is a lone fold inside its own card, so it needs
   neither the divider nor the padding that separate a stack of chapters. */
.polchapter.solo { border-top: 0; padding: 0; }
.annpast { margin-top: 10px; }
.polcount { font-size: 0.75rem; color: var(--pen); font-weight: 400; margin-left: 4px; }
.kbactions { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-top: 8px; font-size: 0.8125rem; }
.kbactions form { margin: 0; }
.kbdelete { display: inline-flex; align-items: center; gap: 10px; }
.kbdelete > summary { cursor: pointer; list-style: none; color: var(--accent); text-decoration: underline; }
.kbdelete > summary::-webkit-details-marker { display: none; }
.kbdelete[open] > summary { color: var(--pen); }
.kbdelete button.linkish { font-weight: 600; }
.kbactions button.primary { font-size: 0.8125rem; padding: 7px 16px; }

/* Past announcements: a quiet link under the bar on Home, and the archive. */
.pastlink { font-size: 0.8125rem; margin: 6px 0 0; text-align: right; }
.pastlist { list-style: none; margin: 0; padding: 0; }
.pastann { padding: 16px 0; border-top: 1px solid var(--soft); }
.pastann:first-child { border-top: 0; padding-top: 0; }
.pastann .annlead { margin-top: 6px; }

/* How we work and Aligning Up: readable paragraphs inside the sections. */
.polmission { font-family: 'Playfair Display', Georgia, serif; font-size: 1.125rem; color: var(--plum); line-height: 1.45; }
.polpara { font-size: 0.9062rem; line-height: 1.65; color: var(--ink); margin-top: 8px; max-width: 760px; }
.kbstart { margin: 14px 0 6px; }
.kbstart > .card { flex: 1 1 300px; }

/* ---- Who to ask, as a flow chart ----
   Two numbered steps joined by a line down the left (1: look it up, 2: what
   is it about), then one card per topic whose path runs top to bottom with
   arrows, ending in a filled pill: the person or form. All of it is lists
   and headings underneath; the line, numbers and arrows are decoration. */
.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.flowchart { list-style: none; margin: 0; padding: 0; }
.flownode { position: relative; display: flex; gap: 14px; padding-bottom: 18px; }
.flownode:last-child { padding-bottom: 0; }
.flownode:not(:last-child)::before {
  content: ''; position: absolute; left: 15px; top: 34px; bottom: 0;
  border-left: 2px dashed var(--accent-12);
}
.flownum {
  flex: none; width: 32px; height: 32px; border-radius: 50%;
  background: var(--accent); color: var(--paper); font-weight: 600; font-size: 0.9375rem;
  display: flex; align-items: center; justify-content: center;
}
.flowbody { flex: 1; min-width: 0; }
.flowhead { font-size: 1.0625rem; color: var(--plum); margin: 4px 0 2px; }
.flowsub { font-size: 0.8125rem; color: var(--pen); margin-bottom: 10px; }
.flowbody .kbsearch { margin: 0; max-width: none; }
.flowtopics { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 12px; }
.flowtopic { border: 1px solid var(--soft); border-radius: 12px; padding: 12px 14px; background: var(--paper); }
.flowtopic h4 { font-size: 0.9375rem; color: var(--ink); margin-bottom: 8px; }
.flowpath { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 0; }
.flowstep { font-size: 0.8438rem; color: var(--ink); line-height: 1.4; }
.flowstep + .flowstep::before {
  content: '\2193'; display: block; color: var(--accent); font-size: 1rem; line-height: 1.3; margin-left: 8px;
}
.flowstep a { color: var(--accent); }
.flowpill {
  display: inline-block; font-weight: 600;
  background: var(--accent-06); border: 1px solid var(--accent-12); border-radius: 999px; padding: 5px 12px;
}
.flowend a { color: var(--accent); text-decoration: none; }
.flowend a:hover, .flowend a:focus-visible { text-decoration: underline; }
.flowtip { font-size: 0.75rem; color: var(--pen); margin-top: 8px; line-height: 1.45; }
.flowmore { font-size: 0.75rem; margin-top: 4px; }
.flowtopic a:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }

/* Compact, for the half-width card on Home: one column, each topic folded. */
.flowchart.compact .flowtopics { grid-template-columns: 1fr; gap: 6px; }
.flowchart.compact .flowtopic { padding: 0; border: 0; border-top: 1px solid var(--soft); border-radius: 0; background: none; }
.flowchart.compact .flowtopic:first-child { border-top: 0; }
.flowchart.compact summary { cursor: pointer; font-size: 0.875rem; padding: 8px 0; color: var(--ink); }
.flowchart.compact summary::marker { color: var(--accent); }
.flowchart.compact summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
.flowchart.compact .flowpath { padding: 0 0 10px 16px; }

/* Jump back in, in two groups: outside programs, then hub pages. */
.jumpgroup { margin-top: 14px; }
.jumpgroup + .jumpgroup { margin-top: 22px; }
.jumpgroup h3 { color: var(--plum); font-size: 1.0625rem; }
.jumpgroup .own { font-size: 0.7812rem; color: var(--pen); margin-bottom: 8px; }

/* HR request: the per-kind hints fold away; the reply box sits under a
   request that is waiting on the person who asked. */
.hrhints summary { cursor: pointer; font-size: 0.8125rem; color: var(--accent); }
.hrhints .annpoints { font-size: 0.8125rem; }
.hrreply { margin: 8px 0 0; justify-content: flex-start; }

/* Every step in a path is a button-shaped pill; the earlier steps outlined,
   the last one filled, so the order reads at a glance. */
.flowpill.step { background: var(--paper); border: 1.5px solid var(--accent); color: var(--ink); font-weight: 500; }
.flowpill.step a { color: var(--accent); text-decoration: none; font-weight: 600; }
.flowpill.step a:hover, .flowpill.step a:focus-visible { text-decoration: underline; }
.flowend .flowpill { background: var(--accent); border-color: var(--accent); color: var(--paper); }
.flowend .flowpill a { color: var(--paper); }

/* Flow step buttons: rounded rectangles, not capsules, so two- and
   three-line steps keep their shape (Cassidy, 2026-10-06); even spacing
   with the arrow centered between steps. */
.flowpath { gap: 0; }
.flowpill { border-radius: 10px; padding: 7px 12px; line-height: 1.35; display: inline-block; max-width: 100%; }
.flowstep + .flowstep::before { margin: 3px 0 3px 14px; line-height: 1; }
.flowtip { margin-top: 10px; }

/* Always 3 across on a full-width screen (Cassidy, 2026-10-06): six topics
   read as two even rows of three, never a lopsided 4 + 2. Two across on a
   tablet, one on a phone. */
.flowchart:not(.compact) .flowtopics { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 900px) { .flowchart:not(.compact) .flowtopics { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .flowchart:not(.compact) .flowtopics { grid-template-columns: 1fr; } }

/* Emphasis on the FIRST step (Cassidy, 2026-10-06): the step to take now is
   the filled purple button; the escalation steps after it are outlined. A
   one-step path is filled. Overrides the earlier last-step fill. */
.flowpath .flowpill,
.flowend .flowpill { background: var(--paper); border: 1.5px solid var(--accent); color: var(--ink); font-weight: 500; }
.flowpath .flowpill a,
.flowend .flowpill a { color: var(--accent); font-weight: 600; }
.flowpath .flowstep:first-child .flowpill { background: var(--accent); border-color: var(--accent); color: var(--paper); font-weight: 600; }
.flowpath .flowstep:first-child .flowpill a { color: var(--paper); }
/* Every step but the final escalation is filled (supervisor AND lead are the
   prominent ones); a one-step path stays filled. */
.flowpath .flowstep:not(:last-child) .flowpill { background: var(--accent); border-color: var(--accent); color: var(--paper); font-weight: 600; }
.flowpath .flowstep:not(:last-child) .flowpill a { color: var(--paper); }
.flowpath.fillall .flowstep .flowpill { background: var(--accent); border-color: var(--accent); color: var(--paper); font-weight: 600; }
.flowpath.fillall .flowstep .flowpill a { color: var(--paper); }
/* Buttons and arrows centered in each topic card (Cassidy, 2026-10-08). */
.flowpath { align-items: center; }
.flowstep { text-align: center; }
.flowstep + .flowstep::before { margin: 3px auto; }
.polbreak { border: 0; border-top: 1px solid var(--soft); margin: 28px 0 6px; }

/* Values as fold-open cards: number and name always, paragraph on click. */
.valuefold { align-self: start; }
.valuefold > summary { cursor: pointer; list-style: none; position: relative; padding-right: 26px; }
.valuefold > summary::-webkit-details-marker { display: none; }
.valuefold > summary::after { content: '+'; position: absolute; right: 0; top: 50%; transform: translateY(-50%); color: var(--accent); font-size: 1.125rem; }
.valuefold[open] > summary::after { content: '\2212'; }
.valuefold > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; border-radius: 6px; }
.valuefold > p { margin-top: 10px; }
/* Closed: the five values sit small in one row. Open: that value takes the
   full width, so opening one never leaves a gap beside it. */
.values .valuefold { flex: 1 1 150px; padding-top: 14px; padding-bottom: 14px; }
.values .valuefold[open] { flex-basis: 100%; }
.values .valuefold h4 { font-size: 1.125rem; }
.values .valuefold:not([open]) { align-self: stretch; }
.values .valuefold > summary { min-height: 100%; }

/* Each value card gets its own color, turquoise through brand purple, so the five
   read as one set (Cassidy, 2026-10-08). Light text on every fill. */
.values .value { --vc: var(--accent); background: var(--vc); border-color: var(--vc); }
.values .value:nth-child(5n+1) { --vc: #2E6E75; }
.values .value:nth-child(5n+2) { --vc: #366582; }
.values .value:nth-child(5n+3) { --vc: #45598C; }
.values .value:nth-child(5n+4) { --vc: #574C8C; }
.values .value:nth-child(5n+5) { --vc: #6E3A78; }
.values .value h4 { color: var(--paper); }
.values .value .valuenum { color: rgba(244, 239, 234, 0.7); }
.values .value p { color: rgba(244, 239, 234, 0.9); }
.values .valuefold > summary::after { color: var(--paper); }
.values .valuefold > summary:focus-visible { outline-color: var(--paper); }

/* ---- CE: what a person tracks ---- */
.trackopt { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 8px; margin: 12px 0; cursor: pointer; }
.trackopt select { font: inherit; }
.emdrset { display: block; }
.emdrset summary { cursor: pointer; }
.emdrset select { margin-top: 8px; }

/* Remove-from-credentialing, tucked away at the foot of a provider card. */
.credremove { margin-top: 12px; }
.credremove summary { cursor: pointer; color: var(--pen); font-size: 0.85rem; }
.credremove form { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 8px; }
.credremove label { font-size: 0.85rem; }

/* Provider cards fold to the name and progress bar. The marker is replaced by
   a plus or minus on the right, same as the Policies sections. */
summary.credhead { cursor: pointer; list-style: none; position: relative; padding-right: 28px; }
summary.credhead::-webkit-details-marker { display: none; }
summary.credhead::after { content: '+'; position: absolute; right: 0; top: 0; font-size: 1.25rem; line-height: 1; color: var(--accent); }
.credprovider[open] > summary.credhead::after { content: '\2212'; }
.credprovider[open] > summary.credhead { margin-bottom: 12px; }
summary.credhead:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; border-radius: 6px; }
/* What is still owed reads on one line on a desktop, not wrapped at 60ch. */
.cetracker .notice.gaps { max-width: none; }

/* ---- Leadership: bus plans ---- */
.busplan .polsub:first-child, .busplan .polpara:first-child { margin-top: 0; }
.busplantable td { vertical-align: top; padding: 6px 10px; }
.busplanform { display: flex; flex-direction: column; gap: 10px; align-items: flex-start; }
