/* Baton base layer
   ================
   The four apps are separate hand-written files with no shared stylesheet, so
   anything that should be true everywhere has had to be written four times —
   and in practice was written nowhere. This file is the start of the shared
   layer: rules that belong to the platform rather than to one console.

   It is linked AFTER each app's inline <style> so it can settle the handful of
   things every console should agree on, and deliberately does nothing else.
   Component consolidation goes in later, once each app's own copy is removed. */


/* 1 · Keyboard focus
   ------------------
   Before this, no console in Baton showed a keyboard user where they were:
   zero :focus-visible rules across all four files, and outline:none set
   explicitly in three of them. Someone working a review queue by keyboard —
   which is how a fast office person will want to work it — was flying blind.

   :focus-visible only fires for keyboard and assistive-tech focus, so a mouse
   click still gives no ring and nothing looks different for existing users.
   !important is here on purpose: the app files suppress outlines with
   higher-specificity selectors (.btn:focus{outline:none}) that this layer would
   otherwise lose to. It is scoped to the outline properties alone, so it cannot
   affect anything else a component sets on focus. */
:is(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--pink, #DF255E) !important;
  outline-offset: 2px !important;
  border-radius: 4px;
}

/* On the dark rails, pink on deep purple is legible but tight. White reads
   cleanly against every rail colour the four apps use. */
.sidebar :is(a, button):focus-visible,
.side :is(a, button):focus-visible,
.sb :is(a, button):focus-visible,
.rail :is(a, button):focus-visible {
  outline-color: #fff !important;
}


/* 2 · Icon-only hit areas
   -----------------------
   The row actions — call, WhatsApp, email, flag — render at roughly 30px in a
   32px row, three abreast, and one of them dials a phone. The obvious fix is to
   make them bigger, but these lists are scanned in bulk and the density is
   worth keeping, so the visible button stays exactly as it is and only the
   clickable area grows, to about 42px, via an overlay that takes no space in
   the layout. Nothing moves; the target stops being a coin toss. */
.iconly { position: relative; }
.iconly::after {
  content: "";
  position: absolute;
  inset: -6px;
  border-radius: 8px;
}

/* Where two of them sit side by side the overlays would overlap and the later
   sibling would swallow the edge of the earlier one, so give each its own
   stacking context and let the visible box decide the boundary. */
.iconly + .iconly::after { inset: -6px -4px; }


/* 3 · Reduced motion
   ------------------
   Toasts, drawers and the rota grid all animate. Respect the system setting. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}


/* ============================================================================
   4 · Aligning the four consoles to the Rota
   ============================================================================
   The Rota is the best-resolved console in Baton, and the difference is not
   decoration — it is density. Rota sets 14px body text, 22px/24px page padding,
   14px between panels, a 236px rail and 13px table cells. Carer Base and
   Onboarding set 15px, 34px/42px, 22px, 246–280px and 14–15px, so the same
   screen holds noticeably less and reads as a looser, less finished product.
   These lists are scanned in thousands; the tighter setting is the right one.

   Everything below pulls the other three onto Rota's measurements. The values
   are Rota's, taken from its stylesheet rather than invented, so this section
   should shrink to nothing as the shared layer grows and each app's own copy is
   deleted. Rota itself is deliberately untouched: it is already correct.
   ========================================================================== */

/* --- 4.1 Base text ------------------------------------------------------- */
body[data-app="carer-base"],
body[data-app="onboarding"] { font-size: 14px; }

/* --- 4.2 Page padding ---------------------------------------------------- */
body[data-app="carer-base"] .main,
body[data-app="onboarding"] .main { padding: 22px 24px 60px; }
/* Client Base pads its scrolling .body rather than .main, so the same numbers
   go there. Its top bar is a white strip across the same column and gets the
   matching side inset, so the two edges line up. */
body[data-app="client-base"] .body { padding: 22px 24px 60px; }
body[data-app="client-base"] .top { padding: 14px 24px; }

/* --- 4.3 The page head --------------------------------------------------- */
/* Rota sets 26px at -.015em, and every console now matches it. */
body[data-app="carer-base"] .hero,
body[data-app="carer-base"] .page-head h1,
body[data-app="client-base"] .head h1,
body[data-app="onboarding"] .display { font-size: 26px; letter-spacing: -.015em; }

/* The standfirst runs the width of the page.
   ------------------------------------------
   It used to be capped at 64ch, which is the right measure for prose you sit
   and read — an article, a report. This is not that. It is one orientation line
   at the top of a working screen, read once and then skipped past forever, and a
   narrow column made it six stacked lines of grey that looked like a pull-quote
   somebody had left in. Set against a 1,200px-wide table it read as a box the
   page was working around rather than a sentence introducing it.

   So it uses the column it is standing in: two or three lines at a laptop width,
   and it stops growing past 1,180px so a very wide monitor does not turn it into
   a single unreadable ribbon. `text-wrap: pretty` keeps the last line from
   landing as one orphaned word. */
body[data-app="carer-base"] .hero-sub,
body[data-app="carer-base"] .page-head .sub,
body[data-app="client-base"] .head p,
body[data-app="onboarding"] .sub,
body[data-app="rota"] .head p {
  max-width: min(100%, 1180px);
  text-wrap: pretty;
}
/* Carer Base reuses .sub inside table cells and drawers, where the cell is the
   measure and this rule has nothing to say. Named here so the selector above
   staying page-head-scoped is deliberate rather than an oversight. */

/* The pink tick before the eyebrow is the one mark that says Baton rather than
   any other admin console. Three of the four had lost it to the text colour. */
body[data-app="carer-base"] .eyebrow::before,
body[data-app="client-base"] .eyebrow::before,
body[data-app="onboarding"] .kicker::before { background: var(--pink, #DF255E); width: 20px; }

/* Client Base has no italic-serif rule at all, and Carer Base only styles the
   accent inside .hero on its dashboard — so on its six inner pages the italic
   would have rendered as a sans italic. Both get the same treatment as Rota. */
body[data-app="client-base"] .head h1 em,
body[data-app="carer-base"] .page-head h1 em {
  font-family: Georgia, 'Times New Roman', serif;
  font-style: italic;
  font-weight: 400;
  letter-spacing: 0;
  color: var(--pink, #DF255E);
}

/* --- 4.4 Panels ---------------------------------------------------------- */
body[data-app="carer-base"] .panel,
body[data-app="client-base"] .panel,
body[data-app="onboarding"] .panel { border-radius: 14px; margin-bottom: 14px; }

/* --- 4.5 Metric cards ---------------------------------------------------- */
/* One card, everywhere: 12px radius, 14/16 padding, label above the figure in
   Poppins 600 10px uppercase, figure at 24px/800. Carer Base's two card classes
   put the figure first in the markup, so they are reversed visually rather than
   rewritten — the reading order is label-then-number either way. */
body[data-app="carer-base"] .stat,
body[data-app="carer-base"] .stg,
body[data-app="client-base"] .kpi,
body[data-app="onboarding"] .stat {
  padding: 14px 16px;
  border-radius: 12px;
}
/* Carer Base's cards hold figure-then-label (.stat) and figure-then-label-then-
   description (.stg). Reversing the container would put the description on top,
   so the label is promoted instead and everything after it keeps its order. */
body[data-app="carer-base"] .stat,
body[data-app="carer-base"] .stg { display: flex; flex-direction: column; }
body[data-app="carer-base"] .stat .l,
body[data-app="carer-base"] .stg .l { order: -1; }

body[data-app="carer-base"] .stat .n,
body[data-app="carer-base"] .stg .n,
body[data-app="client-base"] .kpi .v,
body[data-app="onboarding"] .stat .num {
  font-size: 24px;
  font-weight: 800;
  letter-spacing: -.025em;
  line-height: 1.1;
  margin: 8px 0 0;
}
body[data-app="carer-base"] .stat .l,
body[data-app="carer-base"] .stg .l,
body[data-app="client-base"] .kpi .l,
body[data-app="onboarding"] .stat .lab {
  font-family: 'Poppins', system-ui, sans-serif;
  font-weight: 600;
  font-size: 10px;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--muted, #6B6580);
  margin: 0;
}

/* Rota fixes the card count per row so the grid does not reflow into a
   different shape at every width. */
body[data-app="carer-base"] .cards,
body[data-app="carer-base"] .pipe,
body[data-app="client-base"] .kpis { gap: 12px; margin-bottom: 20px; }
body[data-app="onboarding"] .statrow { gap: 12px; margin-bottom: 20px; }

/* --- 4.6 Buttons --------------------------------------------------------- */
body[data-app="carer-base"] .btn,
body[data-app="client-base"] .btn,
body[data-app="onboarding"] .btn { padding: 8px 15px; font-size: 12.5px; border-radius: 9px; }
body[data-app="carer-base"] .btn.small,
body[data-app="onboarding"] .btn.sm { padding: 5px 10px; font-size: 11.5px; }

/* --- 4.7 Tables ---------------------------------------------------------- */
/* Rota gives a row room on the side and centres the cell; Carer Base was 5px
   tighter on both axes and top-aligned, which is what made its rows look
   cramped and ragged next to the rota's. */
body[data-app="carer-base"] th,
body[data-app="client-base"] th,
body[data-app="onboarding"] table.grid th { font-size: 10px; letter-spacing: .08em; padding: 10px 17px; }
body[data-app="carer-base"] td,
body[data-app="client-base"] td,
body[data-app="onboarding"] table.grid td { font-size: 13px; padding: 11px 17px; vertical-align: middle; }
/* Client Base sets its own tighter padding on a couple of dense tables. Those
   keep it — this is the default the rest of its rows fall back to. */
body[data-app="client-base"] table.tight th,
body[data-app="client-base"] table.tight td { padding: 9px 13px; }

/* --- 4.8 The rail -------------------------------------------------------- */
body[data-app="carer-base"] .sidebar { width: 236px; }
body[data-app="carer-base"] .main { margin-left: 236px; }
body[data-app="onboarding"] .sidebar { width: 236px; }
body[data-app="onboarding"] .main { margin-left: 236px; }

/* Rota marks the current item with a 16% tint of the accent and keeps the text
   white. Carer Base and Client Base invert it — a solid light bar with dark ink
   — which is the single loudest reason the rails read as different products. */
body[data-app="carer-base"] .nav a.active,
body[data-app="client-base"] .nav a.on {
  background: rgba(223, 37, 94, .16);
  color: #fff;
  font-weight: 600;
}
body[data-app="client-base"] .nav a.on { background: rgba(127, 166, 220, .18); }

/* Onboarding's nav items are square-edged full-bleed rows at 14.5px with a
   border-left marker; every other console uses a 9px-radius pill at 13px. */
body[data-app="onboarding"] .nav a {
  padding: 9px 11px;
  margin: 0 8px;
  border-radius: 9px;
  font-size: 13px;
  border-left: 0;
}
body[data-app="onboarding"] .nav a.active {
  background: rgba(223, 37, 94, .16);
  color: #fff;
}
body[data-app="onboarding"] .nav .section { font-size: 9.5px; letter-spacing: .16em; padding: 15px 19px 6px; }

/* --- 4.9 The three copies of one card ------------------------------------ */
/* .split .s and .chan-split .s are byte-for-byte identical in Carer Base's
   stylesheet, and .reach-split is the same look a third time. All three are the
   metric card under another name, so they get the card the rest of the platform
   uses rather than a fourth variant of it. */
body[data-app="carer-base"] .split .s,
body[data-app="carer-base"] .chan-split .s,
body[data-app="carer-base"] .reach-split .s {
  display: flex;
  flex-direction: column;
  padding: 14px 16px;
  border-radius: 12px;
}
body[data-app="carer-base"] .split .s .l,
body[data-app="carer-base"] .chan-split .s .l,
body[data-app="carer-base"] .reach-split .s .l {
  order: -1;
  font-family: 'Poppins', system-ui, sans-serif;
  font-weight: 600;
  font-size: 10px;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--muted, #6B6580);
  margin: 0;
}
body[data-app="carer-base"] .split .s .n,
body[data-app="carer-base"] .chan-split .s .n,
body[data-app="carer-base"] .reach-split .s .n {
  font-size: 24px;
  font-weight: 800;
  letter-spacing: -.025em;
  line-height: 1.1;
  margin: 8px 0 0;
}
body[data-app="carer-base"] .split,
body[data-app="carer-base"] .chan-split,
body[data-app="carer-base"] .reach-split { gap: 12px; margin-bottom: 20px; }

/* --- 4.10 One sign-in screen --------------------------------------------- */
/* Carer Base and Client Base share a host and a Supabase session, so signing in
   to either already signs you in to both. Only the screens differed — a purple
   card with the logo and a pink rule on one side, a flat navy card with neither
   on the other. Client Base takes Carer Base's, which is the better of the two,
   and the accent goes to WAC pink on both: this is the front door, and the front
   door is the brand rather than the console behind it. */
body[data-app="client-base"] .gate {
  background: var(--rail, #16294D);
  background-image: radial-gradient(ellipse 60% 55% at 88% 8%, rgba(223, 37, 94, .30), transparent 70%);
}
body[data-app="client-base"] .gate .card { padding: 38px 36px 34px; }
body[data-app="client-base"] .gate h1 {
  font-family: 'Poppins', system-ui, sans-serif;
  font-weight: 800;
  font-size: 21px;
  letter-spacing: -.015em;
  margin: 0 0 5px;
}
body[data-app="client-base"] .signin-logo { height: 30px; width: auto; display: block; }
body[data-app="client-base"] .signin-rule {
  width: 40px; height: 3px; border-radius: 2px;
  background: var(--pink, #DF255E); margin: 20px 0 22px;
}
body[data-app="client-base"] .gate .btn.pri {
  background: var(--pink, #DF255E);
  border-color: var(--pink, #DF255E);
  color: #fff;
}
body[data-app="client-base"] .gate a { color: var(--purple, #35276A); }
body[data-app="client-base"] .signin-foot {
  margin-top: 26px; padding-top: 16px;
  border-top: 1px solid var(--line, #E7E2EE);
  font-size: 11px; line-height: 1.6; color: var(--muted, #6B6580);
}
body[data-app="client-base"] .signin-foot .baton {
  font-family: Georgia, serif; font-style: italic; color: var(--gold, #C9A24B);
}

/* --- 4.11 Rails that can outgrow the window ------------------------------ */
/* Every rail is a fixed-height flex column with overflow:hidden, so once the nav
   is taller than the viewport the items at the bottom are silently clipped —
   no scrollbar, no cue, they are simply not there. The rota was within 18px of
   that before the switch and the sibling-workspace group went in, and a laptop
   at 800px would already have lost the last few.
   Let the nav scroll inside the rail and keep the footer where it is. min-height:0
   is what allows a flex child to shrink below its content in the first place. */
.rail, .sidebar, aside.sidebar { display: flex; flex-direction: column; }
.rail .nav, .sidebar .nav, aside.sidebar .nav {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
}
.rail .railfoot, .sidebar .railfoot { flex: none; }

/* --- 4.12 The lifecycle, as cards, on both bases ------------------------- */
/* Carer Base has always shown its lifecycle on the page as a row of cards you
   click into; Client Base showed the same four stages only as a mode bar in the
   rail. Two controls for one idea, and the page one was the one people found
   first. Client Base now renders the same card row, using the same class names,
   so this block is the shared definition rather than a copy — Carer Base already
   declares .pipe/.stg inline and gets its density from 4.5 above.
   The cards carry data-mode, the same attribute the rail buttons carry, so the
   click is the rail's click and cannot drift from it. */
body[data-app="client-base"] .pipe {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px;
  margin-bottom: 20px;
}
body[data-app="client-base"] .stg {
  position: relative;
  background: var(--card, #fff);
  border: 1px solid var(--line, #E7E2EE);
  border-radius: 12px;
  padding: 14px 16px 20px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
body[data-app="client-base"] .stg.click { cursor: pointer; transition: box-shadow .15s, transform .15s; }
body[data-app="client-base"] .stg.click:hover { box-shadow: 0 6px 20px -10px rgba(26,26,46,.3); transform: translateY(-1px); }
/* Where you already are is not a destination. It keeps the accent edge the rail
   gives the selected mode, loses the lift, and says so instead of inviting a
   click that would do nothing. */
body[data-app="client-base"] .stg.here {
  border-color: var(--accent, #1F3A6E);
  box-shadow: inset 3px 0 0 var(--accent, #1F3A6E);
  cursor: default;
}
body[data-app="client-base"] .stg.here:hover { box-shadow: inset 3px 0 0 var(--accent, #1F3A6E); transform: none; }
body[data-app="client-base"] .stg.here .go { opacity: 1; color: var(--muted, #6B6580); }
body[data-app="client-base"] .stg .top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
body[data-app="client-base"] .stg .n {
  font-family: 'Poppins', system-ui, sans-serif;
  font-weight: 800; font-size: 24px; line-height: 1.1;
  letter-spacing: -.025em; margin: 8px 0 0;
  font-variant-numeric: tabular-nums;
}
body[data-app="client-base"] .stg .l {
  order: -1;
  display: flex; align-items: center; gap: 7px;
  font-family: 'Poppins', system-ui, sans-serif;
  font-weight: 600; font-size: 10px; letter-spacing: .09em;
  text-transform: uppercase; color: var(--muted, #6B6580); margin: 0;
}
body[data-app="client-base"] .stg .l:before {
  content: ''; width: 8px; height: 8px; border-radius: 50%;
  background: var(--c); flex: none;
}
body[data-app="client-base"] .stg .d { font-size: 11.5px; color: var(--muted, #6B6580); margin-top: 4px; line-height: 1.4; }
body[data-app="client-base"] .stg .own {
  font-family: ui-monospace, SFMono-Regular, monospace;
  font-size: 9.5px; letter-spacing: .08em; color: var(--muted, #6B6580); flex: none;
}
body[data-app="client-base"] .stg .go {
  position: absolute; right: 12px; bottom: 10px;
  font-size: 11px; color: var(--accent, #1F3A6E); font-weight: 600;
  opacity: 0; transition: opacity .15s;
}
body[data-app="client-base"] .stg.click:hover .go { opacity: 1; }

/* --- 4.13 The messages tab ------------------------------------------------ */
/* Above the workspaces in every rail, because Messages is not a section of the
   app you are in — it is the one queue belonging to the whole platform, and the
   only one where a person is actively waiting on us. Same shape everywhere, so
   it is findable without looking. The count is threads NOT PICKED UP; a badge
   that never reaches zero stops being read within a week. */
.msgtab {
  display: flex; align-items: center; gap: 10px;
  margin: 0 0 4px; padding: 10px 11px;
  border-radius: 10px; text-decoration: none;
  background: rgba(255, 255, 255, .07);
  border: 1px solid rgba(255, 255, 255, .12);
  color: rgba(255, 255, 255, .82);
  font-family: 'Poppins', system-ui, sans-serif; font-weight: 600; font-size: 12.5px;
}
.msgtab:hover { background: rgba(255, 255, 255, .13); color: #fff; }
.msgtab .mi { width: 15px; height: 15px; flex: none; display: block; }
.msgtab .mi svg { width: 15px; height: 15px; display: block; }
.msgtab .mt { flex: 1; }
.msgtab .mn {
  font-family: ui-monospace, SFMono-Regular, monospace; font-size: 11px;
  font-variant-numeric: tabular-nums; opacity: .55;
}
/* Anything unowned turns it pink. Nothing waiting and it goes quiet, which is
   the only way the pink keeps meaning something. */
.msgtab.hot {
  background: rgba(223, 37, 94, .16);
  border-color: rgba(223, 37, 94, .42);
  color: #fff;
}
.msgtab.hot .mn {
  background: var(--pink, #DF255E); color: #fff; opacity: 1;
  border-radius: 100px; padding: 1px 8px; font-family: 'Poppins', system-ui, sans-serif; font-weight: 600;
}
