/* ==========================================================================
   SmartDocs 8.2 — Component layer
   Plain CSS built on the tokens. Tailwind handles layout and responsive
   variants; this file holds the components whose sizes are specified exactly,
   so a button is `.btn` rather than six utility classes repeated everywhere.
   ========================================================================== */

/* --------------------------------------------------------------- base ---- */

*, *::before, *::after { box-sizing: border-box; }

html { font-size: 16px; }

body {
  margin: 0;
  background: var(--background);
  color: var(--foreground);
  font-family: "Source Sans 3", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 13px;
  line-height: 1.45;
  /* Set once, globally, so amounts and dates stay column aligned everywhere. */
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
}

code, kbd, .mono, .ref {
  font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
}

/* One focus rule for the whole application, not one per component. */
*:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* Skip link. Visible only on keyboard focus. */
.skip-link {
  position: absolute;
  left: 8px;
  top: -60px;
  z-index: 200;
  padding: 10px 16px;
  background: var(--primary);
  color: var(--primary-foreground);
  font-weight: 600;
  border-radius: var(--r-md);
  transition: top .15s ease;
}
.skip-link:focus { top: 8px; }

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ------------------------------------------------------------ top bar ---- */

/* White. Always white in the light theme, never a navy gradient.
   Everything in the bar is 34px tall and sits on one centre line, with
   hairline dividers separating the four jobs the bar does: who you are,
   where you can go, what is waiting, and your account. */

.topbar {
  height: var(--topbar-h);
  background: var(--card);
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 var(--gutter);
  position: sticky;
  top: 0;
  z-index: 60;
}

.topbar-divider {
  width: 1px; height: 22px; flex-shrink: 0;
  background: var(--border);
}

.brand {
  display: flex; align-items: center; gap: 9px; flex-shrink: 0;
  text-decoration: none; color: inherit;
  padding: 4px 6px 4px 0; border-radius: var(--r-md);
}
.brand-mark {
  width: 28px; height: 28px; border-radius: 7px;
  background: var(--primary); color: var(--primary-foreground);
  display: grid; place-items: center;
  font-size: 11.5px; font-weight: 700; letter-spacing: -.02em;
  flex-shrink: 0;
}
.brand-name {
  font-size: 13.5px; font-weight: 700; letter-spacing: -.015em;
  line-height: 1.15; display: block;
}
.brand-app {
  font-size: 9.5px; font-weight: 700; color: var(--muted-foreground);
  text-transform: uppercase; letter-spacing: .1em; line-height: 1.15;
  display: block;
}

/* Module pills. Filled rounded pill for the selected item, never an underline.
   Solid fill is 8.73:1 both directions; a tint of the same navy cannot reach
   the 3:1 that SC 1.4.11 requires of a state indicator without failing 1.4.3. */
.modbar { display: flex; align-items: center; gap: 1px; flex-shrink: 0; }

.pill {
  height: 34px;
  min-height: 34px;
  padding: 0 10px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--muted-foreground);
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  white-space: nowrap;
  transition: background-color .12s ease, color .12s ease;
}
.pill .ico { opacity: .85; }
.pill:hover { background: var(--primary-soft); color: var(--primary); }
.pill:hover .ico { opacity: 1; }
.pill:active { background: var(--secondary); }
.pill[aria-current="page"] {
  background: var(--primary);
  color: var(--primary-foreground);
  font-weight: 600;
}
.pill[aria-current="page"] .ico { opacity: 1; }
.pill[aria-current="page"]:hover { background: var(--primary-pressed); }

/* Right side utilities.
   Three jobs, three clusters, hairlines between them: find something,
   see what is waiting, reach your own account. */
.utils { display: flex; align-items: center; gap: 8px; margin-left: auto; flex-shrink: 0; }
.utils-group { display: flex; align-items: center; gap: 2px; }

.iconbtn {
  width: 34px; height: 34px;
  display: grid; place-items: center;
  border: 0; border-radius: var(--r-md);
  background: transparent; color: var(--muted-foreground);
  cursor: pointer; position: relative;
  transition: background-color .12s ease, color .12s ease;
}
.iconbtn:hover { background: var(--secondary); color: var(--foreground); }
.iconbtn[aria-expanded="true"] { background: var(--primary-soft); color: var(--primary); }

/* One count style, not three competing reds. The number is also exposed as
   visually hidden text, because a figure in a coloured circle is not read
   out as a count. */
.dot-count {
  position: absolute; top: 3px; right: 2px;
  min-width: 16px; height: 16px; padding: 0 4px;
  border-radius: 999px;
  background: var(--destructive); color: #fff;
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 9.5px; font-weight: 600; line-height: 16px;
  text-align: center;
  box-shadow: 0 0 0 2px var(--card);
}

.avatarbtn {
  width: 34px; height: 34px; padding: 0;
  display: grid; place-items: center;
  border: 0; border-radius: 999px; background: transparent;
  cursor: pointer;
}
.avatarbtn:hover .avatar { box-shadow: 0 0 0 2px var(--primary-soft); }
.avatarbtn[aria-expanded="true"] .avatar { box-shadow: 0 0 0 2px var(--primary); }
.avatar {
  width: 30px; height: 30px; border-radius: 999px;
  background: var(--navy); color: var(--navy-foreground);
  display: grid; place-items: center;
  font-size: 11px; font-weight: 700; letter-spacing: .02em;
  transition: box-shadow .12s ease;
}

/* Global search. A filled field rather than an outlined one, so it reads as
   somewhere to type rather than as another button. */
.searchbox {
  display: flex; align-items: center; gap: 8px;
  height: 34px; padding: 0 10px;
  flex: 0 1 240px; min-width: 150px;
  border: 1px solid var(--input); border-radius: var(--r-md);
  background: var(--secondary); color: var(--muted-foreground);
  cursor: text;
  transition: background-color .12s ease, border-color .12s ease;
}
.searchbox:hover { background: var(--muted); }
.searchbox:focus-within {
  background: var(--card);
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--primary-soft);
}
.searchbox input {
  border: 0; outline: 0; background: transparent; color: var(--foreground);
  font: inherit; font-size: 12.5px; width: 100%; min-width: 0;
  /* Fills the field so the control itself clears the 24px target minimum,
     rather than relying on the padding of its container. */
  height: 100%;
}
.searchbox kbd {
  flex-shrink: 0;
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 10px; padding: 1px 5px; border-radius: 4px;
  background: var(--card); border: 1px solid var(--border);
  color: var(--muted-foreground);
}

/* ------------------------------------------------- menus and popovers ---- */
/* Anchored to their trigger and sized to content. Never full bleed. */

.menu {
  position: absolute;
  z-index: 70;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-pop);
  padding: 12px;
  display: none;
}
.menu[data-open="true"] { display: block; }

.menu-cols { display: flex; gap: 6px; align-items: flex-start; }
.menu-col { width: 214px; }

.menu-eyebrow {
  font-size: 10px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .08em; color: var(--muted-foreground);
  padding: 6px 8px 5px;
}

.menu-item {
  display: flex; align-items: center; gap: 9px;
  width: 100%;
  min-height: 32px;
  padding: 6px 8px;
  border: 0; border-radius: var(--r-sm);
  background: transparent; color: var(--foreground);
  font: inherit; font-size: 12.5px;
  text-align: left; text-decoration: none;
  cursor: pointer;
}
.menu-item:hover { background: var(--secondary); }
.menu-item[aria-current="page"] { background: var(--primary-soft); color: var(--primary); font-weight: 600; }
.menu-item .ico { color: var(--muted-foreground); flex-shrink: 0; }
.menu-item:hover .ico, .menu-item[aria-current="page"] .ico { color: var(--primary); }

.menu-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px; padding: 2px 8px 10px; margin-bottom: 6px;
  border-bottom: 1px solid var(--border);
}
.menu-title { font-size: 12.5px; font-weight: 700; }

.popover { width: 260px; }
.popover .menu-item { min-height: 34px; }

/* ------------------------------------------------------------ buttons ---- */

.btn {
  height: 34px;
  padding: 0 13px;
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  border: 1px solid transparent; border-radius: var(--r-md);
  font: inherit; font-size: 13px; font-weight: 600;
  white-space: nowrap; cursor: pointer; text-decoration: none;
  transition: background-color .12s ease, border-color .12s ease;
}
.btn-sm { height: 28px; padding: 0 10px; font-size: 12px; }
.btn-lg { height: 40px; padding: 0 18px; }

.btn-primary     { background: var(--primary); color: var(--primary-foreground); }
.btn-primary:hover { background: var(--primary-pressed); }
.btn-outline     { background: var(--card); color: var(--foreground); border-color: var(--input); }
.btn-outline:hover { background: var(--secondary); }
.btn-secondary   { background: var(--secondary); color: var(--secondary-foreground); }
.btn-ghost       { background: transparent; color: var(--muted-foreground); }
.btn-ghost:hover { background: var(--secondary); color: var(--foreground); }
.btn-ai          { background: var(--ai); color: #fff; }
.btn-destructive { background: var(--destructive); color: #fff; }
.btn:disabled    { opacity: .5; cursor: not-allowed; }

/* -------------------------------------------------------------- badge ---- */
/* The 6px dot means status never depends on colour alone. */

.badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 1px 9px;
  border-radius: var(--r-md);
  font-size: 11.5px; font-weight: 600;
  white-space: nowrap;
}
.badge::before {
  content: ""; width: 6px; height: 6px; border-radius: 999px;
  background: currentColor; flex-shrink: 0;
}
.badge-neutral { background: var(--secondary); color: var(--secondary-foreground); }
.badge-info    { background: var(--info-soft); color: var(--info); }
.badge-success { background: var(--success-soft); color: var(--success); }
.badge-warning { background: var(--warning-soft); color: var(--warning); }
.badge-danger  { background: var(--destructive-soft); color: var(--destructive); }
.badge-ai      { background: var(--ai-soft); color: var(--ai); }

/* --------------------------------------------------------------- card ---- */

.card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-panel);
}
.card-head {
  padding: 9px 14px;
  border-bottom: 1px solid var(--border);
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
.card-title { font-size: 14px; font-weight: 600; }
.card-body { padding: 14px; }
.card-foot {
  padding: 9px 14px; border-top: 1px solid var(--border);
  background: var(--surface);
  font-size: 11.5px; color: var(--muted-foreground);
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
}

/* ------------------------------------------------------- screen header ---- */
/* A single baseline row, not a bordered card.
   The card version stood 106px tall to carry three lines of text, most of
   it padding and border. The breadcrumb went with it: the selected module
   pill already says which module you are in and the title says which
   screen, so `Home / Admin / Configuration` said nothing twice.
   Title and description share one baseline and wrap only when they must,
   which takes the block to roughly 38px. */

.screen-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px 20px; flex-wrap: wrap;
  padding: 0 2px 12px;
  border-bottom: 1px solid var(--border);
}
.screen-head-text {
  display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; min-width: 0;
}
.screen-title {
  font-size: 20px; font-weight: 700; letter-spacing: -.02em;
  line-height: 1.2; margin: 0;
}
.screen-desc {
  font-size: 12.5px; color: var(--muted-foreground);
  margin: 0; max-width: 72ch;
}
.screen-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* ----------------------------------------------------------- kpi tiles ---- */

.kpi { padding: 12px 14px; }
.kpi-label {
  font-size: 10.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .07em; color: var(--muted-foreground);
}
.kpi-figure { font-size: 22px; font-weight: 700; line-height: 1.15; margin-top: 5px; letter-spacing: -.02em; }
.kpi-hero   { font-size: 30px; font-weight: 700; line-height: 1.1; letter-spacing: -.02em; }
.kpi-meta   { font-size: 11.5px; color: var(--muted-foreground); margin-top: 3px; }

/* -------------------------------------------------------------- table ---- */

.table-wrap { overflow-x: auto; }
table.tbl { width: 100%; border-collapse: collapse; font-size: 12.5px; }
table.tbl th {
  position: sticky; top: 0; z-index: 2;
  background: var(--surface);
  text-align: left;
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .07em;
  color: var(--muted-foreground);
  padding: 8px 12px;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
table.tbl td {
  padding: 7px 12px;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}
table.tbl tbody tr:hover { background: var(--secondary); }
table.tbl tbody tr { cursor: pointer; }
table.tbl tbody tr:focus-visible { outline: 2px solid var(--ring); outline-offset: -2px; }
.num { text-align: right; font-variant-numeric: tabular-nums; }
.ref { font-size: 12px; color: var(--muted-foreground); }

/* Toolbar above a table */
.toolbar {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 10px 14px; border-bottom: 1px solid var(--border);
}
.chip {
  height: 28px; padding: 0 10px;
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid var(--input); border-radius: 999px;
  background: var(--card); color: var(--muted-foreground);
  font-size: 12px; font-weight: 500; cursor: pointer;
}
.chip:hover { background: var(--secondary); }
.chip[aria-pressed="true"] {
  background: var(--primary); border-color: var(--primary);
  color: var(--primary-foreground); font-weight: 600;
}

.filter-input {
  height: 30px; min-width: 200px; padding: 0 10px;
  border: 1px solid var(--input); border-radius: var(--r-md);
  background: var(--card); color: var(--foreground);
  font: inherit; font-size: 12.5px;
}

/* ------------------------------------------------------- queue rows ---- */

.qrow {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
}
.qrow:hover { background: var(--secondary); }
.qrow-icon {
  width: 32px; height: 32px; flex-shrink: 0;
  border-radius: var(--r-md);
  background: var(--primary-soft); color: var(--primary);
  display: grid; place-items: center;
}
.qrow-title { font-size: 13px; font-weight: 600; }
.qrow-sub { font-size: 11.5px; color: var(--muted-foreground); margin-top: 1px; }
.qrow-actions { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }

/* ---------------------------------------------------------- hub cards ---- */

.hub-card {
  display: flex; flex-direction: column; gap: 4px;
  padding: 13px 14px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  text-align: left; cursor: pointer;
  font: inherit; color: inherit;
  transition: border-color .12s ease, box-shadow .12s ease;
}
.hub-card:hover { border-color: var(--primary); box-shadow: var(--shadow-panel); }
.hub-card-top { display: flex; align-items: center; gap: 9px; }
.hub-card-ico {
  width: 30px; height: 30px; flex-shrink: 0;
  border-radius: var(--r-md);
  background: var(--primary-soft); color: var(--primary);
  display: grid; place-items: center;
}
.hub-card-name { font-size: 13.5px; font-weight: 600; }
/* One line, always. A tile description is a label, not a sentence, and a
   grid where some tiles run to two lines and others to one reads as untidy
   before it reads as informative. Descriptions are written to 46 characters;
   the clamp is the guarantee if one ever slips past that. The full text
   stays in the DOM, so a screen reader still hears all of it. */
.hub-card-desc {
  font-size: 12px; color: var(--muted-foreground);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.hub-card-meta {
  font-size: 11px; font-weight: 600; color: var(--muted-foreground);
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  margin-top: 2px;
}

/* ----------------------------------------------------------- settings ---- */

.set-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 24px; padding: 12px 14px;
  border-bottom: 1px solid var(--border);
}
.set-label { font-size: 13px; font-weight: 600; }
.set-desc { font-size: 12px; color: var(--muted-foreground); margin-top: 1px; }
.set-control { flex-shrink: 0; }

/* A rail row carries an icon tile, its name and a count pill. The icon is
   the point: sixteen lines of plain text are a list, and the eye has
   nothing to aim at. Selection is carried by four things at once, an
   accent bar, a tint, a filled icon tile and a weight change, so it never
   rests on colour alone. */

.rail-section + .rail-section {
  margin-top: 14px; padding-top: 12px;
  border-top: 1px solid var(--border);
}
.rail-section-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px; padding: 0 10px 6px;
}

.rail-item {
  position: relative;
  display: flex; align-items: center; gap: 10px;
  width: 100%; min-height: 38px; padding: 5px 8px 5px 11px;
  border: 0; border-radius: var(--r-md);
  background: transparent; color: var(--foreground);
  font: inherit; font-size: 12.5px; text-align: left; cursor: pointer;
  transition: background-color .12s ease;
}
.rail-item:hover { background: var(--secondary); }

.rail-ico {
  width: 26px; height: 26px; flex-shrink: 0;
  border-radius: var(--r-sm);
  background: var(--secondary); color: var(--muted-foreground);
  display: grid; place-items: center;
  transition: background-color .14s ease, color .14s ease;
}
.rail-item:hover .rail-ico { background: var(--primary-soft); color: var(--primary); }

.rail-count {
  margin-left: auto; flex-shrink: 0;
  min-width: 24px; padding: 1px 7px;
  border-radius: 999px;
  background: var(--secondary); color: var(--muted-foreground);
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 10.5px; font-weight: 600; text-align: center;
  transition: background-color .14s ease, color .14s ease;
}

.rail-item[aria-selected="true"] {
  background: var(--primary-soft);
  color: var(--primary);
  font-weight: 600;
}
.rail-item[aria-selected="true"]::before {
  content: "";
  position: absolute; left: 0; top: 7px; bottom: 7px;
  width: 3px; border-radius: 0 3px 3px 0;
  background: var(--primary);
}
.rail-item[aria-selected="true"] .rail-ico,
.rail-item[aria-selected="true"] .rail-count {
  background: var(--primary); color: var(--primary-foreground);
}

/* Rail plus pane. Used by Settings and by the Hub in its railed mode.
   The rail sticks below the top bar and scrolls on its own, because a
   sixteen group rail is taller than most screens.
   Below 900px the rail becomes a block above the pane rather than a
   squeezed column, and stops being sticky. */
.rail-layout { grid-template-columns: 268px minmax(0, 1fr); }
.rail-layout > aside {
  position: sticky;
  top: calc(var(--topbar-h) + 16px);
  max-height: calc(100vh - var(--topbar-h) - 32px);
  overflow-y: auto;
}
@media (max-width: 900px) {
  .rail-layout { grid-template-columns: minmax(0, 1fr); }
  .rail-layout > aside { position: static; max-height: 240px; }
}

/* A group heading inside the right pane. Same shape as the Settings
   panel head so the two archetypes read as one family. */
.pane-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; margin-bottom: 12px;
}
.pane-title { font-size: 16px; font-weight: 700; margin: 2px 0 0; }
/* One line, like the tile descriptions beneath it. The cap was 78ch, which
   held the text to 484px and wrapped it even when the panel had a thousand
   pixels to give. The cap is gone and the clamp is the guarantee; group
   descriptions are written to 75 characters. */
.pane-desc {
  font-size: 12.5px; color: var(--muted-foreground); margin-top: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Without this the flex child refuses to shrink and the ellipsis never
   fires, it just pushes the count off the end instead. */
.pane-head > div { min-width: 0; }

/* Below about 520px the longest group description cannot fit a line, and a
   sentence cut off mid-word with an ellipsis tells a reader less than no
   sentence at all. It is dropped rather than truncated. Nothing is lost:
   the group name is still the heading, the count is still beside it, and
   every tile underneath carries its own description. */
@media (max-width: 520px) {
  .pane-desc { display: none; }
}
.pane-count {
  font-size: 11px; font-weight: 600; color: var(--muted-foreground);
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  white-space: nowrap;
}

.rail-aside { padding: 10px; }

/* Sub-sections inside a group's pane. A grid of nine or ten tiles stops
   being scannable, so past about six the group carries sections of its
   own. Below that they add structure nobody needed. */
.pane-sub + .pane-sub { margin-top: 18px; }
.pane-sub-head {
  display: flex; align-items: center; gap: 8px;
  margin: 0 0 8px; padding-bottom: 6px;
  border-bottom: 1px solid var(--border);
  font-size: 11px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .08em; color: var(--muted-foreground);
}
.pane-sub-head .rail-count { margin-left: 0; }

/* The group a card came from, shown only in search results where the
   cards are drawn from every group at once. */
.hub-card-group {
  font-size: 10px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .07em; color: var(--primary);
  margin-bottom: 2px;
}

select.ctl, input.ctl {
  height: 30px; min-width: 170px; padding: 0 8px;
  border: 1px solid var(--input); border-radius: var(--r-md);
  background: var(--card); color: var(--foreground);
  font: inherit; font-size: 12.5px;
}

/* Switch, 44x24 so the touch target clears WCAG 2.5.8 comfortably */
.switch {
  width: 44px; height: 24px; flex-shrink: 0;
  border: 0; border-radius: 999px;
  background: var(--input); cursor: pointer;
  position: relative; transition: background-color .15s ease;
}
.switch::after {
  content: ""; position: absolute; top: 3px; left: 3px;
  width: 18px; height: 18px; border-radius: 999px;
  background: #fff; transition: transform .15s ease;
  box-shadow: 0 1px 2px rgb(0 0 0 / .3);
}
.switch[aria-checked="true"] { background: var(--primary); }
.switch[aria-checked="true"]::after { transform: translateX(20px); }

/* -------------------------------------------------------------- misc ---- */

.eyebrow {
  font-size: 10px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .08em; color: var(--muted-foreground);
}

.empty {
  padding: 40px 20px; text-align: center; color: var(--muted-foreground);
}
.empty-title { font-size: 14px; font-weight: 600; color: var(--foreground); margin-bottom: 4px; }

.notice {
  display: flex; gap: 10px; align-items: flex-start;
  padding: 11px 13px; border-radius: var(--r-md);
  border: 1px dashed var(--ai); background: var(--ai-soft); color: var(--ai);
  font-size: 12.5px;
}

/* Bar chart, CSS only */
.bars { display: flex; align-items: flex-end; gap: 10px; height: 150px; }
.bar-col { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 6px; height: 100%; justify-content: flex-end; }
.bar {
  width: 100%; max-width: 38px; border-radius: 4px 4px 0 0;
  background: var(--primary); min-height: 3px;
}
.bar-label { font-size: 10.5px; color: var(--muted-foreground); font-weight: 600; }

.legend { display: flex; flex-direction: column; gap: 7px; }
.legend-row { display: flex; align-items: center; gap: 8px; font-size: 12px; }
.legend-swatch { width: 9px; height: 9px; border-radius: 2px; flex-shrink: 0; }

/* ------------------------------------------------------- responsive ---- */

/* The bar gives things up in a fixed order as it narrows, so the pills stay
   whole for as long as possible. Eight icon-and-label pills need about
   780px, which is most of a 1280px bar once the brand and the utilities
   have taken theirs.

     below 1400   the brand drops to its mark, and search to its icon.
                  Both are recoverable: the mark still goes home, the icon
                  still opens search.
     below 1160   the pills collapse into the Modules overflow menu.

   The pills never shrink and never scroll. A squashed pill with its label
   clipped is worse than an honest overflow menu. */

@media (max-width: 1400px) {
  .brand-text { display: none; }
  .searchbox { flex: 0 0 34px; min-width: 0; padding: 0; justify-content: center; }
  .searchbox input, .searchbox kbd { display: none; }
}

@media (max-width: 1160px) {
  .modbar { display: none; }
  .modbar-overflow { display: inline-flex; }
  .topbar > .topbar-divider { display: none; }
}
@media (min-width: 1161px) {
  .modbar-overflow { display: none; }
}

/* Below 640px a table becomes one card per row carrying the columns that
   matter. Horizontal scroll is not a mobile treatment. */
@media (max-width: 640px) {
  /* Tighten the bar so brand, Modules, search and the three utilities fit
     a 375px phone without the bar itself scrolling. The appearance toggle
     is a prototype control rather than a product feature, so it drops out
     here and the operating system preference decides instead. */
  .topbar { padding: 0 12px; gap: 8px; }
  #themebtn { display: none; }

  table.tbl thead { display: none; }
  table.tbl, table.tbl tbody, table.tbl tr, table.tbl td { display: block; width: 100%; }
  table.tbl tr {
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    margin-bottom: 8px;
    padding: 4px 0;
  }
  table.tbl td {
    border: 0;
    display: flex; align-items: baseline; justify-content: space-between; gap: 16px;
    padding: 5px 12px;
  }
  table.tbl td[data-label]::before {
    content: attr(data-label);
    font-size: 10px; font-weight: 700; text-transform: uppercase;
    letter-spacing: .07em; color: var(--muted-foreground);
    flex-shrink: 0;
  }
  /* Columns marked secondary drop out entirely on a phone */
  table.tbl td[data-priority="low"] { display: none; }
  .num { text-align: left; }

  .menu { left: 8px !important; right: 8px; width: auto; max-width: none; }
  .menu-cols { flex-direction: column; }
  .menu-col { width: 100%; }

  .qrow { flex-wrap: wrap; }
  .qrow-actions { width: 100%; padding-left: 44px; }

  /* Every primary action reaches 44px on a phone */
  .screen-actions .btn { height: 44px; flex: 1 1 auto; }
}

/* ==========================================================================
   DEVICE TREATMENTS

   One layout that behaves like the thing it is running on.

     phone    below 768px   bottom tab bar, sheets that rise from the
                            bottom edge, 44px targets, safe area respected
     tablet   768 to 1023   two columns, touch targets kept at 44px
     laptop   1024 to 1399  the full desktop layout, brand and search
                            abbreviated
     desktop  1400 and up   everything
     wide     1600 and up   five tile columns rather than four

   Nothing here is a separate stylesheet or a separate page. It is the same
   markup, told how to sit.
   ========================================================================== */

/* ---------------------------------------------------- phone: bottom nav ---- */

.bottomnav { display: none; }

@media (max-width: 767px) {
  .bottomnav {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    position: fixed; left: 0; right: 0; bottom: 0;
    z-index: 70;
    background: var(--card);
    border-top: 1px solid var(--border);
    /* Clears the home indicator on an iPhone. */
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
  .bottomnav-item {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 3px;
    min-height: calc(var(--bottomnav-h) - 1px); padding: 7px 2px 8px;
    border: 0; background: transparent;
    color: var(--muted-foreground);
    font: inherit; font-size: 10.5px; font-weight: 600;
    cursor: pointer; position: relative;
    -webkit-tap-highlight-color: transparent;
  }
  .bottomnav-item[aria-current="page"] { color: var(--primary); }
  /* Selection is a filled tile plus a colour plus a weight change, never
     colour on its own. */
  .bottomnav-item[aria-current="page"] .bottomnav-ico {
    background: var(--primary); color: var(--primary-foreground);
  }
  .bottomnav-ico {
    width: 30px; height: 26px; border-radius: 999px;
    display: grid; place-items: center;
    background: transparent;
    transition: background-color .14s ease, color .14s ease;
  }

  /* Nothing hides behind the bar. */
  main#main { padding-bottom: calc(var(--bottomnav-h) + 20px + env(safe-area-inset-bottom, 0px)) !important; }

  /* The bottom bar is the navigation on a phone, so the overflow pill in
     the top bar would be a second way to do the same thing. */
  .modbar-overflow { display: none !important; }

  /* Menus rise from the bottom edge, the way a phone sheet does, rather
     than hanging off a trigger that may be nowhere near the thumb. */
  .menu {
    position: fixed !important;
    left: 0 !important; right: 0 !important;
    top: auto !important;
    /* Rests on top of the tab bar rather than under it. The bar stays
       reachable, and the sheet's last item is not hidden behind it. */
    bottom: calc(var(--bottomnav-h) + env(safe-area-inset-bottom, 0px)) !important;
    width: auto !important; max-width: none;
    max-height: 70vh; overflow-y: auto;
    border-radius: var(--r-xl) var(--r-xl) 0 0;
    border-left: 0; border-right: 0; border-bottom: 0;
    padding: 8px 12px 14px;
    box-shadow: 0 -8px 40px -12px oklch(0.3 0.05 250 / .35);
    /* No entrance animation.
       It was tried twice. A transform rise stalled at its opening frame and
       left the sheet sitting over the tab bar, hiding its own last row. An
       opacity fade stalled the same way and left the sheet invisible. An
       animation that has not finished is a layout an animation is holding
       hostage, and animations get throttled: background tab, low power
       mode, a browser that decided not to paint. The grab handle and the
       bottom edge say sheet on their own. */
  }
  /* The grab handle every phone sheet has. */
  .menu::before {
    content: "";
    display: block; width: 36px; height: 4px;
    margin: 4px auto 10px;
    border-radius: 999px; background: var(--input);
  }

  /* Everything a thumb has to hit clears 44px. */
  .menu-item, .rail-item, .qrow { min-height: 44px; }
  .iconbtn, .avatarbtn { width: 40px; height: 40px; }
  .btn { height: 40px; }
  .btn-sm { height: 36px; }
  .chip { height: 36px; padding: 0 14px; }
  .hub-card { padding: 15px 16px; }
}

/* ------------------------------------------------------ tablet and up ---- */

@media (min-width: 768px) and (max-width: 1023px) {
  /* A tablet is touched, not pointed at, so the targets stay large even
     though the layout is closer to the desktop one. */
  .menu-item, .rail-item { min-height: 42px; }
  .btn { height: 38px; }
  .iconbtn, .avatarbtn { width: 38px; height: 38px; }
  .qrow { min-height: 56px; }
}

/* ------------------------------------------------------------- 320px ---- */
/* WCAG 1.4.10 asks for no loss of content at 320 CSS pixels. */

@media (max-width: 380px) {
  :root { --gutter: 12px; }
  .screen-title { font-size: 18px; }
  .hub-card-name { font-size: 13px; }
  .bottomnav-item { font-size: 10px; }
  .brand-mark { width: 26px; height: 26px; }
}

/* --------------------------------------------------------- big screens ---- */

@media (min-width: 1600px) {
  :root { --gutter: 28px; }
  .rail-layout { grid-template-columns: 300px minmax(0, 1fr); }
}

/* -------------------------------------------------- pointer and motion ---- */

/* Hover styling belongs to devices that can hover. On a touch screen a
   hover rule sticks after a tap and looks like a stuck selection. */
@media (hover: none) {
  .pill:hover, .iconbtn:hover, .rail-item:hover,
  .menu-item:hover, .chip:hover, .searchbox:hover { background: transparent; }
  .rail-item:hover .rail-ico { background: var(--secondary); color: var(--muted-foreground); }
  .hub-card:hover { border-color: var(--border); box-shadow: none; }
  table.tbl tbody tr:hover { background: transparent; }
}

/* Landscape on a short screen: the sheet must not swallow the page. */
@media (max-height: 460px) {
  .menu { max-height: 88vh; }
}
