/* Kaarya console — light only, by design. Tokens come from tokens.css. */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--canvas);
  color: var(--ink);
  font-family: var(--family-sans);
  font-size: var(--size-base);
  line-height: var(--leading-base);
  -webkit-font-smoothing: antialiased;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: var(--radius-sm); }

h1, h2, h3 { margin: 0; font-weight: var(--weight-semibold); letter-spacing: -.01em; line-height: var(--leading-tight); }
h1 { font-size: var(--size-xl); }
h2 { font-size: var(--size-md); }
h3 { font-size: var(--size-base); margin-top: var(--space-5); margin-bottom: var(--space-2); }
p { margin: 0 0 var(--space-3); }

.muted { color: var(--ink-muted); }
.mono { font-family: var(--family-mono); font-size: var(--size-sm); }
.small { font-size: var(--size-xs); }
.num { text-align: right; font-variant-numeric: tabular-nums; }
.spaced { margin-top: var(--space-5); }
.lede { color: var(--ink-2); font-size: var(--size-md); max-width: 70ch; margin-bottom: var(--space-5); }
/* An empty screen is still a screen somebody is looking at.
 *
 * "Nobody is in right now." set in grey against nothing reads as a page that
 * failed to load. The same sentence centred, with room around it and a line
 * saying what will fill it, reads as a shop that has not opened yet — which is
 * the truth, and a different feeling entirely. */
.empty {
  color: var(--ink-muted);
  padding: var(--space-8) var(--space-5);
  margin: 0;
  text-align: center;
}
.empty-state {
  display: flex; flex-direction: column; align-items: center; gap: var(--space-2);
  padding: var(--space-9) var(--space-5);
  text-align: center;
}
.empty-state .mark {
  display: grid; place-items: center;
  width: 44px; height: 44px; margin-bottom: var(--space-2);
  border-radius: var(--radius-pill);
  background: var(--surface-2); color: var(--ink-faint);
  font-size: var(--size-lg);
}
.empty-state h3 { margin: 0; font-size: var(--size-md); color: var(--ink); }
.empty-state p { margin: 0; max-width: 44ch; color: var(--ink-muted); font-size: var(--size-sm); }
.empty-state .btn { margin-top: var(--space-3); }
.plain { list-style: none; margin: 0; padding: 0; }
.plain li { padding: var(--space-1) 0; }

/* ---------- shell ---------- */

.shell { display: grid; grid-template-columns: 232px minmax(0, 1fr); min-height: 100vh; }

.sidebar {
  position: sticky; top: 0; align-self: start; height: 100vh;
  display: flex; flex-direction: column;
  background: var(--surface);
  border-right: 1px solid var(--rule);
  padding: var(--space-5) var(--space-4);
  /* The column is exactly the height of the window and never taller, so the
   * list inside it has somewhere to scroll rather than spilling past the
   * bottom of the screen. */
  overflow: hidden;
}

.brand { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-7); text-decoration: none; }
.brand:hover { text-decoration: none; }
.brand-mark {
  width: 30px; height: 30px; flex: none;
  display: grid; place-items: center;
  background: var(--accent); color: var(--accent-ink);
  border-radius: var(--radius-md);
  font-weight: var(--weight-semibold); font-size: var(--size-md);
}
/* The business, then what it does, on two lines.
 *
 * They used to be one run of text with a space between, so "Demo Business Gym
 * & Fitness" wrapped wherever it happened to fit — usually mid-phrase, which
 * reads as one long confusing name rather than a name and a trade. */
.brand-name {
  display: flex; flex-direction: column; gap: 1px;
  color: var(--ink); font-weight: var(--weight-semibold); letter-spacing: -.01em;
  min-width: 0;
}
.brand-name em {
  font-style: normal;
  color: var(--ink-faint);
  font-weight: var(--weight-regular);
  font-size: var(--size-xs);
  line-height: 1.25;
}

/* The menu, and the only part of the sidebar that scrolls.
 *
 * The longest trade puts thirty entries here — around a thousand pixels of
 * list — inside a column fixed at the height of the window. Without this the
 * last third simply could not be reached: no scrollbar, no overflow, the items
 * just stopped. A laptop screen hid Setup entirely.
 *
 * min-height: 0 is the part that does the work. A flex child will not shrink
 * below the height of its own content without it, so overflow-y alone has
 * nothing to overflow and quietly does nothing — which is why this reads as a
 * missing scrollbar rather than a broken one.
 */
.sidebar nav {
  display: flex; flex-direction: column; gap: 2px;
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  /* Room for the last item to clear the footer rule. */
  padding-bottom: var(--space-3);
}
.sidebar nav a {
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  color: var(--ink-2);
  font-size: var(--size-base);
  transition: background var(--motion-fast) var(--motion-ease), color var(--motion-fast) var(--motion-ease);
}
.sidebar nav a:hover { background: var(--surface-2); text-decoration: none; }
.sidebar nav a.on { background: var(--accent-wash); color: var(--accent); font-weight: var(--weight-medium); }

.sidebar-foot { margin-top: auto; padding-top: var(--space-5); border-top: 1px solid var(--rule); }
.who { display: flex; flex-direction: column; margin-bottom: var(--space-2); }
.who strong { font-size: var(--size-base); font-weight: var(--weight-medium); }
.who span { font-size: var(--size-xs); color: var(--ink-faint); text-transform: capitalize; }

.main { min-width: 0; display: flex; flex-direction: column; }

/* The page header.
 *
 * Sticky, because on a long table the one thing you still need after scrolling
 * is to know which screen you are on and to reach its action. The rule beneath
 * is the only border; the shadow appears only once the page has moved, so a
 * screen that fits does not carry a line it never earned. */
.topbar {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-4);
  padding: var(--space-5) var(--space-7);
  border-bottom: 1px solid var(--rule);
  background: var(--canvas);
  position: sticky; top: 0; z-index: 5;
}
.topbar h1 {
  font-size: var(--size-xl);
  letter-spacing: -.02em;
  line-height: var(--leading-tight);
}
.topbar-actions { display: flex; align-items: center; gap: var(--space-3); }

.content { padding: var(--space-6) var(--space-7) var(--space-10); display: flex; flex-direction: column; gap: var(--space-5); }

/* ---------- cards and grids ---------- */

/* A card is a surface with something on it, not a box drawn round some text.
 *
 * The border alone read as a wireframe: correct, and flat. The shadow does the
 * separating and the border only firms up the edge, which is why both are
 * softer than they were. */
.card {
  background: var(--canvas);
  border: 1px solid var(--rule);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  box-shadow: var(--shadow-sm);
}
.card > h2:first-child { margin-bottom: var(--space-4); }
.card.callout { border-left: 3px solid var(--caution); background: var(--caution-wash); box-shadow: none; }

/* A title on the left, whatever acts on it on the right. Enough screens were
 * doing this by hand, slightly differently each time, that it wanted a name. */
.card-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--space-4); margin-bottom: var(--space-4);
}
.card-head h2 { margin: 0; }
.card-head .muted { font-size: var(--size-sm); }

/* Full-bleed inside a card: a table should meet the card's edge rather than
 * sit in a second, smaller box of its own. */
.card > .table:last-child { margin-bottom: calc(var(--space-6) * -1 + var(--space-2)); }

.grid-2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); gap: var(--space-5); }

/* ---------- stats ---------- */

/* The figures a screen leads with.
 *
 * One surface with hairline dividers rather than a row of separate boxes: they
 * are one reading, and five bordered rectangles in a row make five things to
 * look at instead of one. */
.stat-row {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 1px; background: var(--rule);
  border: 1px solid var(--rule); border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}
.stat {
  background: var(--canvas); padding: var(--space-5);
  display: flex; flex-direction: column; gap: var(--space-1);
}
.stat-label {
  font-size: var(--size-xs); text-transform: uppercase; letter-spacing: .08em;
  color: var(--ink-faint); font-weight: var(--weight-medium);
}
.stat-value {
  font-size: var(--size-2xl); font-weight: var(--weight-semibold);
  /* Tabular figures so a column of amounts lines up on the decimal rather than
   * shimmying about as the digits change. */
  font-variant-numeric: tabular-nums; letter-spacing: -.02em;
  line-height: var(--leading-tight);
}
.stat-value.is-critical { color: var(--critical); }

/* How it moved. Never colour alone — the arrow carries the same meaning for a
 * reader who cannot tell the green from the red. */
.stat-delta {
  display: inline-flex; align-items: center; gap: var(--space-1);
  font-size: var(--size-sm); font-weight: var(--weight-medium);
  font-variant-numeric: tabular-nums;
  color: var(--ink-muted);
}
.stat-delta.up { color: var(--positive); }
.stat-delta.down { color: var(--critical); }
.stat-delta.up::before { content: "▲"; font-size: 9px; }
.stat-delta.down::before { content: "▼"; font-size: 9px; }
.stat-note { font-size: var(--size-sm); color: var(--ink-muted); }

/* ---------- tables ---------- */

.table { width: 100%; border-collapse: collapse; font-size: var(--size-base); }
.table th, .table td {
  text-align: left; padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--rule); vertical-align: middle;
}
/* Every figure in a table is tabular, everywhere, without each screen having to
 * remember. A column of amounts that jitters as the digits change is the
 * clearest sign nobody looked at it. */
.table .num, .table .mono { font-variant-numeric: tabular-nums; }
.table th:first-child, .table td:first-child { padding-left: 0; }
.table th:last-child, .table td:last-child { padding-right: 0; }
.table thead th {
  font-size: var(--size-xs); text-transform: uppercase; letter-spacing: .07em;
  color: var(--ink-faint); font-weight: var(--weight-semibold);
  border-bottom-color: var(--rule-strong);
}
.table tbody tr:last-child td { border-bottom: none; }
.table tbody tr:hover { background: var(--surface); }
/* A row that leads somewhere says so before it is clicked. */
.table tbody tr a { text-decoration: none; }
.table tbody tr:hover a { text-decoration: underline; }
.table td .mono { display: block; color: var(--ink-faint); }

/* A secondary line under the main one in a cell -- an address under a name, a
 * job title under a role. Set inline they ran together into one long line and
 * widened the column; the point of a second line is that it is a second line. */
.table td > .small { display: block; margin-top: 2px; line-height: 1.35; }
.table td .person { display: inline-flex; align-items: center; gap: var(--space-2); }

/* A table cell is the one place a long address must be allowed to break: the
 * column has a width, and an unbreakable string simply pushes past it. */
.table td .breakable { overflow-wrap: anywhere; }

/* ---------- chips and tags ---------- */

.chip {
  display: inline-block; padding: 2px var(--space-2);
  border-radius: var(--radius-pill);
  font-size: var(--size-xs); font-weight: var(--weight-medium);
  text-transform: capitalize;
  background: var(--surface-2); color: var(--ink-2);
}
.chip.active { background: var(--positive-wash); color: var(--positive); }
.chip.trial { background: var(--info-wash); color: var(--info); }
.chip.suspended { background: var(--critical-wash); color: var(--critical); }
.chip.cancelled { background: var(--surface-2); color: var(--ink-muted); }
.chip.info { background: var(--info-wash); color: var(--info); }

.tags { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.tag {
  display: inline-block; padding: 2px var(--space-2);
  border: 1px solid var(--rule); border-radius: var(--radius-sm);
  font-size: var(--size-xs); color: var(--ink-2); text-transform: capitalize;
}

.swatch { display: inline-block; width: 14px; height: 14px; border-radius: var(--radius-sm); border: 1px solid var(--rule); vertical-align: -2px; margin-right: var(--space-2); }

/* ---------- bars ---------- */

.bars { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-3); }
.bars li { display: grid; grid-template-columns: 130px 1fr 40px; align-items: center; gap: var(--space-3); }
.bar-label { font-size: var(--size-base); }
.bar { display: block; height: 8px; background: var(--surface-2); border-radius: var(--radius-pill); overflow: hidden; }
.bar i { display: block; height: 100%; background: var(--accent); border-radius: var(--radius-pill); }
.bar-value { font-variant-numeric: tabular-nums; text-align: right; color: var(--ink-muted); font-size: var(--size-sm); }

/* ---------- pairs ---------- */

.pairs { display: grid; grid-template-columns: 130px 1fr; gap: var(--space-2) var(--space-4); margin: 0; }
.pairs dt { color: var(--ink-muted); font-size: var(--size-sm); }
.pairs dd { margin: 0; }

/* ---------- forms ---------- */

.field { display: flex; flex-direction: column; gap: var(--space-2); margin-bottom: var(--space-4); }
.field > span { font-size: var(--size-sm); font-weight: var(--weight-medium); color: var(--ink-2); }
.field small { font-size: var(--size-xs); color: var(--ink-faint); }
.field-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--space-4); }

/* Every text-like control, named by what it is not.
 *
 * This used to list the types it wanted — text, email, password, number,
 * search — which missed seventy-two controls across the product. Two ways:
 *
 * input[type=text] does not match <input name="login">. An input with no type
 * attribute behaves as a text box but carries no attribute to match, so the
 * sign-in page styled the password field and left the email field at the
 * browser default. They rendered at different widths, side by side, which is
 * exactly the sort of thing that makes a product look unfinished.
 *
 * And every type nobody thought to add — date, time, tel — stayed raw. Naming
 * what is excluded instead means date pickers, telephone fields and whatever
 * HTML adds next are all styled without anybody remembering to.
 */
input:not([type=hidden]):not([type=checkbox]):not([type=radio]):not([type=file]):not([type=submit]):not([type=button]):not([type=image]):not([type=range]):not([type=color]),
select, textarea {
  width: 100%;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius-sm);
  background: var(--canvas);
  color: var(--ink);
  font-family: inherit;
  font-size: var(--size-base);
  transition: border-color var(--motion-fast) var(--motion-ease), box-shadow var(--motion-fast) var(--motion-ease);
}
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-wash);
}
input[readonly] { background: var(--surface); color: var(--ink-muted); }

/* Native date and time pickers.
 *
 * They arrive with their own calendar button and an intrinsic width of their
 * own, so left alone they sit narrower than every field around them and their
 * icon presses against the border. A row of fields where one is a different
 * size is the detail that reads as unfinished. */
input[type=date], input[type=time], input[type=datetime-local], input[type=month] {
  min-height: 38px;
  padding-right: var(--space-2);
}
input[type=date]::-webkit-calendar-picker-indicator,
input[type=time]::-webkit-calendar-picker-indicator {
  opacity: .55;
  cursor: pointer;
}
input[type=date]:hover::-webkit-calendar-picker-indicator,
input[type=time]:hover::-webkit-calendar-picker-indicator { opacity: 1; }

.switches { display: flex; flex-wrap: wrap; gap: var(--space-5); margin-top: var(--space-4); }
.switch { display: inline-flex; align-items: center; gap: var(--space-2); font-size: var(--size-base); }
.switch input { width: auto; }

.check-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: var(--space-3); }
.check-grid.three { grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
.check {
  display: flex; align-items: flex-start; gap: var(--space-3);
  padding: var(--space-3);
  border: 1px solid var(--rule); border-radius: var(--radius-sm);
  cursor: pointer;
  transition: border-color var(--motion-fast) var(--motion-ease), background var(--motion-fast) var(--motion-ease);
}
.check:hover { border-color: var(--rule-strong); background: var(--surface); }
.check input { width: auto; margin-top: 3px; flex: none; }
.check span { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.check strong { font-weight: var(--weight-medium); font-size: var(--size-base); }
.check em { font-style: normal; font-size: var(--size-xs); color: var(--ink-faint); }
.check:has(input:checked) { border-color: var(--accent); background: var(--accent-wash); }

.pack-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: var(--space-3); margin-bottom: var(--space-4); }
.pack { display: flex; align-items: flex-start; gap: var(--space-3); padding: var(--space-4); border: 1px solid var(--rule); border-radius: var(--radius-md); cursor: pointer; }
.pack:hover { border-color: var(--rule-strong); background: var(--surface); }
.pack input { width: auto; margin-top: 3px; flex: none; }
.pack span { display: flex; flex-direction: column; gap: var(--space-1); }
.pack em { font-style: normal; font-size: var(--size-sm); color: var(--ink-muted); }
.pack:has(input:checked) { border-color: var(--accent); background: var(--accent-wash); }
.engine-tags { display: flex; gap: var(--space-1); margin-top: var(--space-1); }

.quota-table input[type=number] { max-width: 140px; }
.quota-table input[type=checkbox] { width: auto; }

/* What to do with the form, under it.
 *
 * These sit outside the card on several screens — the form wraps the card and
 * the buttons follow it — and with no space of their own they butted straight
 * up against the card's bottom edge, so the border appeared to run through the
 * button. A row of actions needs room above it whether it is inside a card or
 * beneath one. */
.form-actions {
  display: flex; justify-content: flex-end; align-items: center;
  gap: var(--space-3);
  margin-top: var(--space-4);
  flex-wrap: wrap;
}

/* Inside a card the padding already supplies the space. */
.card > .form-actions:last-child { margin-top: var(--space-5); }

/* On a phone the actions go full width and the primary one goes last, under
 * the thumb rather than across the screen from it. */
@media (max-width: 560px) {
  .form-actions { flex-direction: column-reverse; align-items: stretch; }
  .form-actions .btn { width: 100%; }
}

/* ---------- buttons ---------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  /* Tall enough to hit on a phone without a second thought. */
  min-height: 38px;
  padding: var(--space-2) var(--space-4);
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius-md);
  background: var(--canvas);
  color: var(--ink);
  font-family: inherit; font-size: var(--size-base); font-weight: var(--weight-medium);
  cursor: pointer; text-decoration: none; white-space: nowrap;
  transition: background var(--motion-fast) var(--motion-ease),
              border-color var(--motion-fast) var(--motion-ease),
              box-shadow var(--motion-fast) var(--motion-ease),
              transform var(--motion-fast) var(--motion-ease);
}
.btn:hover { background: var(--surface); border-color: var(--ink-faint); text-decoration: none; }
/* A press that moves. One pixel is enough to feel and too little to notice. */
.btn:active { transform: translateY(1px); }
.btn:focus-visible { outline: none; box-shadow: var(--shadow-ring); border-color: var(--accent); }
.btn[disabled], .btn.is-busy { opacity: .55; cursor: not-allowed; transform: none; }

.btn.primary {
  background: var(--accent); border-color: var(--accent); color: var(--accent-ink);
  box-shadow: var(--shadow-sm);
}
.btn.primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }

.btn.danger { border-color: var(--critical); color: var(--critical); background: var(--canvas); }
.btn.danger:hover { background: var(--critical-wash); border-color: var(--critical); }

/* No border, no fill — for the action beside a real one, where two framed
 * buttons side by side would make neither look like the answer. */
.btn.quiet { border-color: transparent; background: transparent; color: var(--ink-2); }
.btn.quiet:hover { background: var(--surface-2); border-color: transparent; }

.btn.small { min-height: 30px; padding: var(--space-1) var(--space-3); font-size: var(--size-sm); }
.btn.block { width: 100%; }

.link { background: none; border: none; padding: 0; color: var(--accent); font: inherit; font-size: var(--size-sm); cursor: pointer; }
.link:hover { text-decoration: underline; }

/* A row of controls: a search box and its button, a filter and its Apply.
 *
 * Aligned to the bottom rather than the middle, because the things in this row
 * are not the same height and never will be. A labelled field is a caption
 * stacked on a control, so centring the row put the button level with the
 * middle of the whole stack -- which is to say floating above the input it
 * belongs to, which is what it looked like.
 *
 * The field's bottom margin has to go with it. Flexbox aligns margin boxes, so
 * bottom-aligning a field that carries 16px underneath would hang the button
 * that far below the input instead -- the same bug upside down. */
.inline { display: flex; align-items: flex-end; gap: var(--space-3); flex-wrap: wrap; }
.inline > .field { margin-bottom: 0; }

/* Anything genuinely unlabelled sits on the control line too, not above it. */
.inline > .btn, .inline > button { flex: none; }

.inline input[type=text], .inline input[type=search] { max-width: 220px; }
.inline select { max-width: 280px; }

/* ---------- filters and pager ---------- */

/* A filter bar: some links that set a view, and a small form or two.
 *
 * Bottom-aligned for the same reason the inline row is -- the things in it are
 * different heights and a labelled control would otherwise sit off the line.
 *
 * The nested form must not wrap. As a flex item it was free to shrink to its
 * narrowest, and .inline lets its own children wrap, so the select took the
 * width and dropped its Show button onto a second line underneath -- a button
 * apparently belonging to nothing, below the row it acts on. */
.filters { display: flex; align-items: flex-end; gap: var(--space-3); flex-wrap: wrap; }
.filters > .inline { flex: none; flex-wrap: nowrap; }
.filters input[type=search] { max-width: 280px; }
.filters select { max-width: 170px; }
.filters-count { margin-left: auto; color: var(--ink-muted); font-size: var(--size-sm); }

.pager { display: flex; gap: var(--space-1); }
.pager a { padding: var(--space-1) var(--space-3); border: 1px solid var(--rule); border-radius: var(--radius-sm); color: var(--ink-2); font-size: var(--size-sm); }
.pager a:hover { background: var(--surface); text-decoration: none; }
.pager a.on { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }

/* ---------- alerts ---------- */

/* Something the screen needs to say before anything else on it.
 *
 * The base carried a coloured left border and no colour to put in it, so an
 * alert with no modifier drew a black bar down its side. Information is the
 * sensible default — most of these are "here is what just happened" — and the
 * one that was missing entirely was the good news, which is why the check-in
 * screen was carrying its success colours inline. */
.alert {
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  font-size: var(--size-base);
  border-left: 3px solid var(--info);
  background: var(--info-wash);
  color: var(--info-ink);
}
.alert.positive { background: var(--positive-wash); border-color: var(--positive); color: var(--positive-ink); }
.alert.critical { background: var(--critical-wash); border-color: var(--critical); color: var(--critical-ink); }
.alert.caution { background: var(--caution-wash); border-color: var(--caution); color: var(--caution-ink); }

/* ---------- detail head ---------- */

.detail-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); flex-wrap: wrap; }
.detail-head > div:first-child { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }

/* ---------- sign in ---------- */

body.bare { background: var(--surface); }
/* The sign-in page.
 *
 * The first thing anybody sees, and for most of a business's staff the only
 * page they will ever look at twice. It was a white card on white — correct,
 * and indistinguishable from a page that had half loaded.
 *
 * The ground is now a very quiet wash of the brand colour, so the card has
 * something to sit on and the whole thing reads as somewhere rather than as
 * nowhere. Everything else stays deliberately plain: this screen has one job,
 * and anything decorative on it is in the way of somebody trying to start work.
 */
.signin {
  min-height: 100vh;
  display: grid; place-items: center;
  padding: var(--space-6);
  background:
    radial-gradient(circle at 18% 0%, var(--accent-wash), transparent 46%),
    radial-gradient(circle at 88% 96%, var(--surface-2), transparent 42%),
    var(--surface);
}

.signin-card {
  width: 100%; max-width: 400px;
  background: var(--canvas);
  border: 1px solid var(--rule);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: var(--space-8) var(--space-7);
}

.signin-head {
  text-align: center; margin-bottom: var(--space-6);
  display: flex; flex-direction: column; align-items: center; gap: var(--space-2);
}
.signin-head .brand-mark {
  width: 44px; height: 44px;
  font-size: var(--size-lg);
  margin-bottom: var(--space-2);
  box-shadow: var(--shadow-sm);
}
.signin-head h1 {
  font-size: var(--size-xl); letter-spacing: -.02em;
  line-height: var(--leading-tight);
}
.signin-head p { color: var(--ink-muted); font-size: var(--size-sm); margin: 0; }

.signin .alert { margin-bottom: var(--space-5); }

/* The button is the only thing on this page anybody came to press. */
.signin-card .btn.primary { margin-top: var(--space-2); min-height: 44px; font-size: var(--size-md); }

/* A line under the card for the thing somebody needs when sign-in is not
 * working — kept off the card so it never competes with it. */
.signin-foot {
  margin-top: var(--space-5); text-align: center;
  font-size: var(--size-sm); color: var(--ink-muted);
}

/* ---------- responsive ---------- */

@media (max-width: 900px) {
  .shell { grid-template-columns: minmax(0, 1fr); }
  .sidebar { position: static; height: auto; flex-direction: row; align-items: center; gap: var(--space-4); padding: var(--space-3) var(--space-4); }
  .brand { margin-bottom: 0; }
  .sidebar { overflow: visible; }
  /* Laid out as a row here, so the vertical scrolling above would trap the menu
   * in a strip a few pixels tall. */
  .sidebar nav { flex-direction: row; flex-wrap: wrap; flex: 0 1 auto; min-height: auto; overflow: visible; padding-bottom: 0; }
  .brand-name { flex-direction: row; align-items: baseline; gap: var(--space-2); }
  .sidebar-foot { margin-top: 0; margin-left: auto; padding-top: 0; border-top: none; }
  .who { display: none; }
  .topbar, .content { padding-left: var(--space-4); padding-right: var(--space-4); }
  .pairs { grid-template-columns: minmax(0, 1fr); gap: var(--space-1); }
  .pairs dt { margin-top: var(--space-2); }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
}

/* ---------- small utilities ---------- */

/* A secondary detail under a name reads as a second line, not a continuation.
 *
 * Twenty-one spans across ten screens were carrying `style="display:block"` to
 * say this, each written out again. Named here once: a table cell that holds a
 * name and a detail is the commonest shape in the product, and the detail
 * belongs beneath. */
.table td strong + .muted,
.table td strong + .small,
.table td strong + br + .muted { display: block; margin-top: 1px; }

.line { display: block; }

/* A reference, an address, a token — something with no spaces that would
 * otherwise push the whole page sideways. */
.breakable { word-break: break-all; overflow-wrap: anywhere; }

/* Components that were living in five different views as inline style. */

/* Why a message never arrived, under the message it belongs to. */
.failed-why { color: var(--critical); font-size: var(--size-sm); }

/* One entry in a list of things people wrote — a review, a note. The rule
 * beneath separates them without boxing each one. */
.feed-row { border-bottom: 1px solid var(--rule); padding: var(--space-4) 0; }
.feed-row:last-child { border-bottom: none; padding-bottom: 0; }

/* The business answering. Indented under what it replies to, so the thread
 * reads in the order it happened. */
.reply {
  border-left: 3px solid var(--rule);
  padding-left: var(--space-4);
  margin-top: var(--space-3);
}

/* An address or a key meant to be copied rather than read. */
.code-line {
  background: var(--surface);
  border: 1px solid var(--rule);
  padding: var(--space-3);
  border-radius: var(--radius-md);
  font-size: var(--size-sm);
}

.bare { border: none; }
