/* =========================================================================
   Ligo Regnskap application shell
   Shared layout and components for the Ligo web apps: sidebar, page header,
   metric tiles, panels, tables, forms, buttons, badges and the login card.
   The language is the minimalistic presentation in training-health: page,
   menu and panels share one surface, groups are drawn with hairlines, labels
   are Fira Code capitals, text is Albert Sans and titles and figures are
   Outfit. Only the outer panel, fields and the hover, focus or active state
   draw a box. Requires colors_and_type.css. Product CSS adds page specific
   rules only.
   ========================================================================= */

html {
  scroll-behavior: smooth;
}

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

body {
  min-width: 320px;
  max-width: 100%;
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-size: var(--fs-ui-body);
  line-height: 1.5;
}

button {
  cursor: pointer;
}

/* Focus is a 1 px line in the primary colour outside a 2 px soft ring.
   Menu items and buttons add it to their hover state, so a keyboard user
   sees a second line around the primary border. Fields draw the line on
   their own border. */
button:focus-visible,
a:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: 1px solid var(--primary);
  outline-offset: 2px;
  box-shadow: 0 0 0 2px var(--primary-soft);
}

::selection {
  background: rgba(var(--primary-rgb), 0.28);
}

/* ---------- Shell grid ---------- */

.control-shell {
  display: grid;
  grid-template-columns: 240px minmax(0, 1fr);
  min-height: 100vh;
}

.content-shell {
  min-width: 0;
}

.control-main {
  min-width: 0;
  width: min(100%, 1440px);
  margin: 0 auto;
  padding: 28px 32px 56px;
}

.control-main > p,
.control-main section p,
.login-page p {
  margin-top: 0;
}

/* ---------- Sidebar ---------- */

.side-rail {
  position: sticky;
  z-index: 80;
  top: 0;
  display: flex;
  height: 100vh;
  height: 100dvh;
  flex-direction: column;
  gap: 18px;
  overflow: hidden auto;
  padding: 14px 12px 0;
  border-right: 1px solid var(--border);
  background: var(--side-bg);
  scrollbar-width: thin;
}

.brand-lockup {
  display: flex;
  min-height: 46px;
  align-items: center;
  gap: 10px;
  padding: 2px 4px 14px;
  border-bottom: 1px solid var(--border);
  color: var(--ink);
}

.brand-lockup:hover {
  color: var(--ink);
}

.brand-mark {
  width: 50px;
  height: 30px;
  flex: none;
  border-radius: var(--radius-sm);
  object-fit: contain;
}

.brand-copy {
  display: grid;
  min-width: 0;
  gap: 1px;
  line-height: 1.3;
}

/* The brand is a name in the text face, the product under it a mono label.
   Both stay on one line at a fixed size, so the label keeps room in the rail
   on every screen instead of dropping a letter to a new line. */
.brand-copy strong,
.brand-copy small {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.brand-copy strong {
  color: var(--ink);
  font: 500 var(--fs-ui-body)/1.35 var(--font-sans);
}

.brand-copy small {
  color: var(--muted);
  font: 400 var(--fs-ui-label)/1.4 var(--font-mono);
}

.side-section {
  min-width: 0;
}

.side-section-system {
  margin-top: auto;
}

.side-section-label {
  display: block;
  margin: 0 11px 6px;
  color: var(--muted);
  font: 400 var(--fs-label)/1.5 var(--font-mono);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
}

.side-nav {
  display: grid;
  gap: 2px;
}

.side-nav a {
  position: relative;
  display: flex;
  min-height: 34px;
  align-items: center;
  gap: 10px;
  padding: 6px 10px;
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  color: var(--muted);
  background: transparent;
  font: 400 var(--fs-label)/1.5 var(--font-mono);
  overflow-wrap: break-word;
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease), color var(--dur) var(--ease);
}

.side-nav a:is(:hover, :focus-visible, .is-active) {
  border-color: var(--primary);
  color: var(--ink);
  background: var(--primary-soft);
}

/* Section links inside the current page mark the visible section with ink
   only, so the page itself stays the one boxed item in the rail. */
.side-nav-anchors a.is-active:not(:hover, :focus-visible) {
  border-color: transparent;
  color: var(--ink);
  background: transparent;
}

.side-nav-text {
  min-width: 0;
  overflow-wrap: break-word;
}

.side-nav svg,
.side-icon-button svg,
.sidebar-mobile-toggle svg {
  width: 16px;
  height: 16px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.nav-badge {
  margin-left: auto;
  padding: 2px 6px;
  border: 1px solid color-mix(in srgb, var(--amber) 45%, var(--border));
  border-radius: var(--radius-md);
  color: var(--muted);
  background: transparent;
  font: 400 var(--fs-label)/1.3 var(--font-mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.system-state {
  display: flex;
  min-width: 0;
  align-items: center;
  gap: 9px;
  padding: 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: transparent;
}

.system-state-dot {
  width: 7px;
  height: 7px;
  flex: none;
  background: var(--green);
}

.system-state > span:last-child {
  display: grid;
  min-width: 0;
}

.system-state strong {
  color: var(--ink);
  font-size: var(--fs-ui-small);
  font-weight: 500;
}

.system-state small {
  margin-top: 2px;
  color: var(--muted);
  font: 400 var(--fs-label)/1.4 var(--font-mono);
  overflow-wrap: break-word;
}

/* The account row stays in view at the bottom of the rail when the links
   need to scroll on short screens. */
.side-footer {
  position: sticky;
  z-index: 1;
  bottom: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 6px;
  margin-top: auto;
  padding: 12px 2px;
  border-top: 1px solid var(--border);
  background: var(--side-bg);
}

.side-section + .side-footer {
  margin-top: auto;
}

.account-copy {
  display: grid;
  min-width: 0;
  gap: 1px;
  padding-left: 8px;
}

/* Name and address wrap so the whole value stays visible in the rail. */
.account-copy strong {
  color: var(--ink);
  font: 500 var(--fs-ui-small)/1.35 var(--font-sans);
  overflow-wrap: break-word;
}

.account-copy small {
  color: var(--muted);
  font: 400 var(--fs-label)/1.4 var(--font-mono);
  overflow-wrap: break-word;
}

.side-icon-button,
.sidebar-mobile-toggle {
  display: grid;
  width: 32px;
  height: 32px;
  place-items: center;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  color: var(--muted);
  background: var(--bg);
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}

.side-icon-button:is(:hover, :focus-visible),
.sidebar-mobile-toggle:is(:hover, :focus-visible, [aria-expanded="true"]) {
  border-color: var(--primary);
  color: var(--ink);
  background: var(--primary-soft);
}

.theme-icon-light {
  display: none;
}

html[data-theme="light"] .theme-icon-dark {
  display: none;
}

html[data-theme="light"] .theme-icon-light {
  display: block;
}

/* The phone bar carries the menu button and the brand. It is hidden while
   the rail is visible. */
.mobile-bar,
.sidebar-mobile-toggle,
.sidebar-backdrop {
  display: none;
}

.mobile-brand {
  display: flex;
  min-width: 0;
  align-items: center;
  gap: 10px;
  color: var(--ink);
}

.mobile-brand:hover {
  color: var(--ink);
}

.mobile-brand .brand-mark {
  width: 40px;
  height: 24px;
}

/* ---------- Collapsed rail ---------- */

/* The logo is the button that folds the rail to its icons on wide screens
   and closes the drawer on phones. The layout script keeps the choice per
   browser and sets it on <html> before the first paint. */
button.brand-lockup {
  width: 100%;
  border: 0;
  border-bottom: 1px solid var(--border);
  background: transparent;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

@media (min-width: 961px) {
  html[data-sidebar="collapsed"] .control-shell {
    grid-template-columns: 64px minmax(0, 1fr);
  }

  html[data-sidebar="collapsed"] .side-rail {
    padding-inline: 8px;
  }

  html[data-sidebar="collapsed"] .brand-lockup {
    justify-content: center;
    padding-inline: 0;
  }

  html[data-sidebar="collapsed"] .brand-mark {
    width: 40px;
  }

  /* Page sections without icons, such as report anchors, return with the
     full rail. */
  html[data-sidebar="collapsed"] :is(.brand-copy, .side-section-label, .nav-badge, .account-copy, .theme-picker > summary > span, .theme-picker-options, .side-section:not(:has(.side-nav svg))) {
    display: none;
  }

  html[data-sidebar="collapsed"] :is(.side-nav a, .theme-picker > summary) {
    justify-content: center;
    gap: 0;
    padding-inline: 0;
    font-size: 0;
  }

  html[data-sidebar="collapsed"] .side-footer {
    grid-template-columns: minmax(0, 1fr);
    justify-items: center;
  }

  html[data-sidebar="collapsed"] .theme-picker {
    justify-self: stretch;
  }
}

/* ---------- Page heading ---------- */

/* The title stands on the page without a rule under it, like the
   training-health pages. Filters sit at its right. */
.page-heading {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 24px;
  margin-bottom: 20px;
  scroll-margin-top: 20px;
}

.page-heading > * {
  min-width: 0;
  max-width: 100%;
}

/* A page kicker stays only where it names the page or its client. It is a
   quiet mono label, never a coloured heading. */
.page-eyebrow,
.section-label,
.section-kicker {
  display: block;
  margin: 0;
  color: var(--muted);
  font: 400 var(--fs-label)/1.5 var(--font-mono);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
}

.page-eyebrow {
  margin-bottom: 8px;
}

.page-heading h1 {
  margin: 0;
  color: var(--ink);
  font: 500 var(--fs-title)/1.15 var(--font-display);
  letter-spacing: -0.025em;
  overflow-wrap: break-word;
}

.page-description {
  max-width: 690px;
  margin: 10px 0 0;
  color: var(--muted);
  font-size: var(--fs-ui-body);
}

.page-heading-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 16px;
  margin-top: 10px;
  color: var(--muted);
  font-size: var(--fs-ui-body);
}

.page-heading-meta strong {
  color: var(--ink);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

.page-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
}

/* ---------- Metric tiles ---------- */

/* A tile is a training-health measurement card: a 7 px status square and a
   mono label, a large Outfit figure and a muted line under it. */
.metric-strip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr));
  gap: 16px;
  margin-bottom: 16px;
}

.metric-item {
  position: relative;
  display: grid;
  min-width: 0;
  align-content: start;
  padding: 18px 18px 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: none;
}

/* The status square comes first and sits on the label's first line. */
.metric-item-top {
  display: flex;
  flex-direction: row-reverse;
  align-items: baseline;
  justify-content: flex-end;
  gap: 8px;
}

.metric-item > span,
.metric-item-top > span {
  min-width: 0;
  color: var(--muted);
  font: 400 var(--fs-label)/1.5 var(--font-mono);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
}

/* The square is filled for a signal and outlined when there is none. */
.metric-status {
  width: 7px;
  height: 7px;
  flex: none;
  border: 1px solid var(--muted);
  background: transparent;
}

.metric-status:is(.is-positive, .is-good) {
  border-color: var(--green);
  background: var(--green);
}

.metric-status:is(.is-negative, .is-bad) {
  border-color: var(--red);
  background: var(--red);
}

.metric-item strong {
  position: relative;
  z-index: 1;
  margin-top: 14px;
  overflow: hidden;
  color: var(--ink);
  font: 500 var(--fs-figure)/1.1 var(--font-display);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.metric-item small {
  position: relative;
  z-index: 1;
  display: flex;
  flex-wrap: wrap;
  gap: 4px 8px;
  margin-top: 8px;
  color: var(--muted);
  font-size: var(--fs-ui-small);
  line-height: 1.5;
  font-variant-numeric: tabular-nums;
}

.metric-change.is-positive,
.metric-change.is-good {
  color: var(--green);
}

.metric-change.is-negative,
.metric-change.is-bad {
  color: var(--red);
}

.metric-change.is-neutral,
.metric-change.is-flat {
  color: var(--muted);
}

/* A tile with a sparkline puts it in its own column beside the change text.
   The text wraps within its column, so the two never overlap. */
.metric-item:has(> .metric-sparkline) {
  grid-template-columns: minmax(0, 1fr) minmax(56px, 36%);
  column-gap: 10px;
}

.metric-item:has(> .metric-sparkline) > :not(small, .metric-sparkline) {
  grid-column: 1 / -1;
}

.metric-sparkline {
  grid-column: 2;
  align-self: end;
  width: 100%;
  height: 26px;
  pointer-events: none;
}

.metric-sparkline svg {
  width: 100%;
  height: 100%;
  overflow: visible;
}

.sparkline-path {
  fill: none;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}

/* ---------- Panels ---------- */

.control-surface,
.report-card {
  min-width: 0;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: none;
  scroll-margin-top: 20px;
}

.surface-spaced {
  margin-top: 16px;
}

/* The panel heading is a mono kicker over an Albert Sans title. Air, not a
   rule, separates it from the content. */
.surface-heading,
.card-heading {
  display: flex;
  min-height: 0;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px 16px;
  margin: 0;
  padding: 16px 16px 10px;
}

/* The title grows and shrinks first. Actions move to their own line only when
   the title and actions no longer fit side by side, so nothing is clipped. */
.surface-heading > :first-child,
.card-heading > :first-child {
  min-width: 0;
  flex: 1 1 14rem;
}

.surface-heading h2,
.card-heading h2 {
  margin: 0;
  color: var(--ink);
  font: 500 15px/1.35 var(--font-sans);
  letter-spacing: 0;
}

.surface-heading .section-label + h2,
.surface-heading .section-kicker + h2,
.card-heading .section-label + h2,
.card-heading .section-kicker + h2 {
  margin-top: 4px;
}

.surface-heading p,
.card-heading p {
  margin: 4px 0 0;
  color: var(--muted);
  font-size: var(--fs-ui-small);
}

.card-total {
  color: var(--ink);
  font-size: var(--fs-ui-small);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

.report-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
  margin-bottom: 16px;
  scroll-margin-top: 20px;
}

.report-grid-wide {
  grid-template-columns: minmax(0, 1fr);
}

/* ---------- Badges ---------- */

/* Chips and badges are mono text in a hairline box on the page surface.
   Status badges add capitals and a 7 px square in the status colour, so the
   colour is never the only signal. */
.quiet-badge,
.level-badge,
.status-badge,
.period-chip,
.status-pill {
  display: inline-flex;
  width: fit-content;
  min-height: 22px;
  align-items: center;
  gap: 7px;
  padding: 3px 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  color: var(--muted);
  background: transparent;
  font: 400 var(--fs-label)/1.2 var(--font-mono);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.status-badge,
.status-pill {
  border-color: color-mix(in srgb, var(--status-color, var(--muted-2)) 40%, var(--border));
  color: var(--ink);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.status-badge::before,
.status-pill::before {
  width: 7px;
  height: 7px;
  flex: none;
  background: var(--status-color, var(--muted-2));
  content: "";
}

.status-dot {
  width: 7px;
  height: 7px;
  background: currentColor;
}

.status-active,
.status-reviewed,
.status-completed,
.status-succeeded,
.status-approved,
.status-done,
.status-ok {
  --status-color: var(--green);
}

.status-running,
.status-unreviewed,
.status-queued,
.status-awaiting_approval,
.status-needs_review,
.status-pending,
.status-warning,
.status-pill {
  --status-color: var(--amber);
}

.status-failed,
.status-rejected,
.status-stale,
.status-cancelled,
.status-deprecated,
.status-error,
.status-blocked {
  --status-color: var(--red);
}

.level-badge {
  min-width: 26px;
  justify-content: center;
  border-color: color-mix(in srgb, var(--primary) 45%, var(--border));
  color: var(--ink);
}

/* ---------- Tables ---------- */

.table-scroll {
  min-width: 0;
  max-width: 100%;
  overflow-x: auto;
  overscroll-behavior-x: contain;
}

/* Every table in the content area reads its header as mono capitals and its
   figures as tabular numbers. Page tables override this freely. */
:where(.control-main) :where(table) {
  font-variant-numeric: tabular-nums;
}

:where(.control-main) :where(thead th) {
  color: var(--muted);
  font-family: var(--font-mono);
  font-weight: 400;
  text-transform: uppercase;
}

.control-table {
  width: 100%;
  border-collapse: collapse;
  text-align: left;
}

.control-table th {
  padding: 9px 14px;
  border-bottom: 1px solid var(--border);
  color: var(--muted);
  background: transparent;
  font: 400 var(--fs-label)/1.4 var(--font-mono);
  text-transform: uppercase;
  white-space: nowrap;
}

.control-table td {
  padding: 10px 14px;
  border-bottom: 1px solid var(--border);
  color: var(--ink);
  font-size: var(--fs-ui-small);
  vertical-align: middle;
}

.control-table th.is-numeric,
.control-table td.is-numeric,
.control-table .is-numeric {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.control-table tbody tr:last-child td {
  border-bottom: 0;
}

.control-table tbody tr:hover td {
  background: var(--primary-soft);
}

.table-primary,
.table-link {
  color: var(--ink);
  font-size: var(--fs-ui-small);
  font-weight: 500;
}

.table-link:hover,
.text-link:hover {
  color: var(--primary);
}

.table-secondary {
  margin-top: 2px;
  color: var(--muted);
  font-size: var(--fs-ui-label);
}

.text-link {
  color: var(--primary);
  font-size: var(--fs-ui-small);
  font-weight: 400;
}

.empty-table {
  padding: 36px 20px !important;
  color: var(--muted);
  text-align: center;
}

/* ---------- Empty states ---------- */

.empty-state-inline {
  display: flex;
  min-height: 120px;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 24px;
  color: var(--muted);
  font-size: var(--fs-ui-small);
}

.empty-state-icon {
  display: grid;
  width: 36px;
  height: 36px;
  flex: none;
  place-items: center;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  color: var(--muted);
  background: transparent;
}

.empty-state-icon svg {
  width: 18px;
  height: 18px;
  stroke-width: 1.25;
}

.empty-state-inline strong {
  display: block;
  color: var(--ink);
  font-size: var(--fs-ui-body);
  font-weight: 500;
}

.empty-state-inline p {
  margin: 2px 0 0;
  color: var(--muted);
  font-size: var(--fs-ui-small);
}

.empty-panel {
  padding: 20px;
}

.empty-panel h2 {
  margin: 0 0 6px;
  color: var(--ink);
  font: 500 15px/1.35 var(--font-sans);
}

.empty-panel p,
.card-empty {
  max-width: 800px;
  margin: 0;
  color: var(--muted);
  font-size: var(--fs-ui-body);
}

.card-empty {
  padding: 16px;
}

.empty-panel ol {
  margin: 10px 0 0;
  padding-left: 18px;
  color: var(--muted);
  font-size: var(--fs-ui-body);
}

.empty-panel code {
  padding: 1px 5px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--ink);
  background: transparent;
  font-size: var(--fs-ui-label);
}

/* ---------- Forms ---------- */

.filter-bar,
.create-bar,
.report-filters {
  display: grid;
  align-items: end;
  gap: 10px;
}

.filter-bar,
.create-bar {
  margin-bottom: 16px;
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: none;
}

.filter-bar {
  grid-template-columns: minmax(230px, 2fr) repeat(3, minmax(140px, 1fr)) auto;
}

.create-bar {
  grid-template-columns: repeat(3, minmax(0, 1fr)) auto;
}

.report-filters {
  grid-template-columns: minmax(200px, 300px) minmax(132px, 168px);
}

.field-group {
  display: grid;
  min-width: 0;
  gap: 6px;
}

.field-label {
  color: var(--muted);
  font: 400 var(--fs-label)/1.5 var(--font-mono);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
}

.control-input,
.control-select,
.control-textarea,
.control-main :where(input:not([type="hidden"]):not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="submit"]):not([type="button"])),
.control-main select,
.control-main textarea {
  width: 100%;
  min-width: 0;
  max-width: 100%;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  color: var(--ink);
  background-color: var(--field-bg);
  font: 400 var(--fs-ui-field)/1.4 var(--font-sans);
  letter-spacing: 0;
  text-transform: none;
  transition: border-color var(--dur) var(--ease), background-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}

.control-input,
.control-select,
.control-main :where(input:not([type="hidden"]):not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="submit"]):not([type="button"])),
.control-main select {
  min-height: 34px;
  padding: 6px 10px;
}

/* Filter values are mono: selects, search and number fields. */
.control-select,
.control-main select,
.control-input:is([type="search"], [type="number"]),
.control-main :where(input[type="search"], input[type="number"]) {
  font-family: var(--font-mono);
}

/* The chevron is drawn from two hairline gradients in the muted colour, so it
   follows the theme without an image. */
.control-select,
.control-main select {
  padding-right: 30px;
  background-image:
    linear-gradient(45deg, transparent calc(50% - 0.5px), var(--muted) calc(50% - 0.5px), var(--muted) calc(50% + 0.5px), transparent calc(50% + 0.5px)),
    linear-gradient(-45deg, transparent calc(50% - 0.5px), var(--muted) calc(50% - 0.5px), var(--muted) calc(50% + 0.5px), transparent calc(50% + 0.5px));
  background-position: right 17px center, right 12px center;
  background-repeat: no-repeat;
  background-size: 5px 5px, 5px 5px;
  appearance: none;
}

.control-select[multiple],
.control-main select[multiple] {
  padding-right: 10px;
  background-image: none;
}

.control-textarea,
.control-main textarea {
  min-height: 84px;
  padding: 8px 10px;
  resize: vertical;
}

.control-main input[type="file"] {
  padding: 4px;
}

.control-main input[type="file"]::file-selector-button {
  min-height: 26px;
  margin-right: 10px;
  padding: 3px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  color: var(--ink);
  background: var(--surface);
  font: inherit;
  cursor: pointer;
}

.control-input::placeholder,
.control-textarea::placeholder,
.control-main input::placeholder,
.control-main textarea::placeholder {
  color: var(--muted-2);
}

/* Hover and focus on bare fields carry no extra weight, so a page rule for its
   own field always wins. */
.control-input:hover,
.control-select:hover,
.control-textarea:hover,
:where(.control-main) :where(input:not([type="checkbox"], [type="radio"], [type="hidden"]), select, textarea):hover {
  border-color: var(--primary);
  background-color: var(--primary-soft);
}

.control-input:focus,
.control-select:focus,
.control-textarea:focus,
:where(.control-main) :where(input:not([type="checkbox"], [type="radio"]), select, textarea):focus {
  border-color: var(--primary);
  outline: 0;
  box-shadow: 0 0 0 2px var(--primary-soft);
}

.check-row {
  display: flex;
  width: fit-content;
  align-items: center;
  gap: 8px;
  color: var(--ink);
  font-size: var(--fs-ui-small);
  cursor: pointer;
}

/* A checkbox is a hairline square that shows a 7 px primary square when it
   is checked, the same mark the badges and legends use. */
.check-row input[type="checkbox"] {
  display: grid;
  width: 15px;
  height: 15px;
  min-height: 0;
  flex: none;
  margin: 0;
  place-content: center;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--field-bg);
  appearance: none;
  cursor: pointer;
  transition: border-color var(--dur) var(--ease), background-color var(--dur) var(--ease);
}

.check-row input[type="checkbox"]::before {
  width: 7px;
  height: 7px;
  background: var(--primary);
  content: "";
  transform: scale(0);
  transition: transform var(--dur-fast) var(--ease);
}

.check-row input[type="checkbox"]:checked {
  border-color: var(--primary);
}

.check-row input[type="checkbox"]:checked::before {
  transform: scale(1);
}

.check-row:hover input[type="checkbox"] {
  border-color: var(--primary);
  background: var(--primary-soft);
}

.form-error {
  margin: 0 0 12px;
  padding: 9px 12px;
  border: 1px solid color-mix(in srgb, var(--red) 40%, var(--border));
  border-radius: var(--radius-md);
  color: var(--red);
  background: transparent;
  font-size: var(--fs-ui-small);
}

.form-error::before,
.flash-message::before {
  display: inline-block;
  width: 7px;
  height: 7px;
  margin-right: 8px;
  background: currentColor;
  content: "";
  vertical-align: 0.05em;
}

.create-bar-error {
  grid-column: 1 / -1;
  margin: 0;
}

.flash-message {
  margin: 0 0 16px;
  padding: 9px 12px;
  border: 1px solid color-mix(in srgb, var(--primary) 40%, var(--border));
  border-radius: var(--radius-md);
  color: var(--ink);
  background: transparent;
  font-size: var(--fs-ui-small);
}

.flash-message::before {
  background: var(--primary);
}

.flash-message.is-error {
  border-color: color-mix(in srgb, var(--red) 40%, var(--border));
}

.flash-message.is-error::before {
  background: var(--red);
}

.inline-form {
  display: inline;
}

/* ---------- Buttons ---------- */

/* Primary is the only filled button. Every other button is a hairline box on
   the surface that takes the primary line and soft fill on hover, focus and
   when active. */
.primary-button,
.secondary-button,
.danger-button {
  display: inline-flex;
  min-height: 34px;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 6px 14px;
  border-radius: var(--radius-md);
  font: 400 var(--fs-ui-small)/1.2 var(--font-sans);
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}

.primary-button {
  border: 1px solid var(--primary);
  color: var(--on-primary);
  background: var(--primary);
  font-weight: 500;
}

.primary-button:is(:hover, :focus-visible) {
  border-color: var(--primary-hover);
  color: var(--on-primary);
  background: var(--primary-hover);
}

.primary-button svg,
.secondary-button svg,
.danger-button svg {
  width: 14px;
  height: 14px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.primary-button-wide {
  width: 100%;
}

.secondary-button {
  border: 1px solid var(--border);
  color: var(--ink);
  background: var(--surface);
}

.secondary-button:is(:hover, :focus-visible, .is-active, [aria-pressed="true"], [aria-expanded="true"]):not(:disabled) {
  border-color: var(--primary);
  color: var(--ink);
  background: var(--primary-soft);
}

.danger-button {
  border: 1px solid color-mix(in srgb, var(--red) 40%, var(--border));
  color: var(--red);
  background: transparent;
}

.danger-button:is(:hover, :focus-visible):not(:disabled) {
  border-color: var(--red);
  color: var(--red);
  background: color-mix(in srgb, var(--red) 8%, transparent);
}

.primary-button:disabled,
.secondary-button:disabled,
.danger-button:disabled {
  opacity: 0.5;
  cursor: default;
}

.ghost-button {
  display: inline-flex;
  min-height: 30px;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 5px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  color: var(--muted);
  background: var(--surface);
  font: 400 var(--fs-ui-small)/1.2 var(--font-sans);
  white-space: nowrap;
  transition: border-color var(--dur) var(--ease), color var(--dur) var(--ease), background var(--dur) var(--ease);
}

.ghost-button:is(:hover, :focus-visible, .is-active, [aria-pressed="true"], [aria-expanded="true"]):not(:disabled) {
  border-color: var(--primary);
  color: var(--ink);
  background: var(--primary-soft);
}

.ghost-button:disabled {
  opacity: 0.5;
  cursor: default;
}

/* Inside a panel, buttons and badges at rest hold their place with air, as in
   training-health: no frame and no fill until hover, focus, a pressed state or
   an open menu gives them the primary line and soft fill. The panel, its
   fields, the primary and danger buttons and the toolbar in the page heading
   keep their frames. Page panels that draw the same outer frame join the
   list. */
:is(.report-card, .control-surface, .filter-bar, .create-bar, .debia-panel, .wh-panel, .wh-board) :is(.secondary-button, .ghost-button):not(:hover:not(:disabled), :focus-visible, .is-active, [aria-pressed="true"], [aria-expanded="true"], details[open] > summary) {
  border-color: transparent;
  background: transparent;
}

/* A badge in a panel or a table row is its 7 px square and mono text. */
:is(.report-card, .control-surface, .filter-bar, .create-bar, .debia-panel, .wh-panel, .wh-board) :is(.status-badge, .status-pill, .period-chip, .quiet-badge, .level-badge) {
  padding-right: 0;
  padding-left: 0;
  border-color: transparent;
}

.ghost-button svg {
  width: 13px;
  height: 13px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.button-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

/* ---------- Pagination ---------- */

.pagination-footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 16px;
  border-top: 1px solid var(--border);
  color: var(--muted);
  font: 400 var(--fs-label)/1.5 var(--font-mono);
  font-variant-numeric: tabular-nums;
}

.pagination-footer nav {
  width: 100%;
}

.pagination-footer nav > div:first-child {
  display: none;
}

.pagination-footer a,
.pagination-footer span {
  color: var(--muted);
}

.pagination-footer a:hover {
  color: var(--ink);
}

.pagination-footer [aria-current="page"] span {
  color: var(--ink);
  font-weight: 500;
}

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

.login-page {
  display: grid;
  min-height: 100vh;
  place-items: center;
  padding: 32px 20px;
  background: var(--bg);
}

.login-shell {
  display: grid;
  width: min(100%, 420px);
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: none;
}

.login-intro {
  display: flex;
  align-items: center;
  padding: 28px 32px 0;
}

.login-brand {
  display: flex;
  width: fit-content;
  align-items: center;
  gap: 12px;
  color: var(--ink);
}

.login-brand:hover {
  color: var(--ink);
}

.login-brand > span {
  display: grid;
  gap: 1px;
  line-height: 1.3;
}

.login-brand strong {
  color: var(--ink);
  font: 500 14px/1.35 var(--font-sans);
}

.login-brand small {
  color: var(--muted);
  font: 400 var(--fs-label)/1.4 var(--font-mono);
}

.brand-mark-large {
  width: 58px;
  height: 35px;
}

.login-form-panel {
  padding: 28px 32px 32px;
}

.login-form-wrap {
  width: 100%;
}

.login-form-wrap h1 {
  margin: 0;
  color: var(--ink);
  font: 500 var(--fs-title)/1.15 var(--font-display);
  letter-spacing: -0.025em;
}

.microsoft-login-button {
  margin-top: 0;
}

.login-page .login-error {
  margin-top: 18px;
}

.login-separator {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 20px 0;
  color: var(--muted);
  font: 400 var(--fs-label)/1.5 var(--font-mono);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
}

.login-separator::before,
.login-separator::after {
  flex: 1;
  height: 1px;
  background: var(--border);
  content: "";
}

.login-form {
  display: grid;
  gap: 18px;
  margin-top: 24px;
}

.login-separator + .login-form {
  margin-top: 0;
}

.login-form .field-label {
  margin-bottom: 0;
}

.login-form .control-input + .field-label {
  margin-top: 14px;
}

.login-form .control-input {
  min-height: 44px;
  padding-inline: 12px;
}

.login-form .check-row {
  margin: 0;
}

.form-field {
  display: grid;
  min-width: 0;
  gap: 8px;
}

.field-help {
  margin: 0;
  color: var(--muted);
  font-size: var(--fs-ui-small);
  line-height: 1.6;
}

.login-form .primary-button,
.login-form .ghost-button {
  min-height: 44px;
}

.login-form .verification-code {
  font-family: var(--font-mono);
  font-size: 22px;
  letter-spacing: 0.24em;
  font-variant-numeric: tabular-nums;
}

.remember-device {
  width: 100%;
  align-items: flex-start;
  gap: 12px;
  padding: 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: transparent;
}

.remember-device input[type="checkbox"] {
  margin-top: 2px;
}

.remember-device strong,
.remember-device small {
  display: block;
}

.remember-device strong {
  color: var(--ink);
  font-size: var(--fs-ui-small);
  font-weight: 500;
}

.remember-device small {
  margin-top: 4px;
  color: var(--muted);
  font-size: var(--fs-ui-small);
  line-height: 1.55;
}

.login-alternatives {
  display: grid;
  justify-items: center;
  gap: 4px;
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
}

.login-alternatives a {
  display: inline-flex;
  align-items: center;
  min-height: 36px;
}

.login-back-link {
  color: var(--muted);
  font-size: var(--fs-ui-small);
}

.login-back-link:hover {
  color: var(--ink);
}

.control-input[aria-invalid="true"] {
  border-color: var(--red);
}

/* ---------- Development notice ---------- */

.development-notice {
  margin: 0;
  padding: 8px 16px;
  border-bottom: 1px solid var(--border);
  color: var(--muted);
  background: var(--bg);
  text-align: center;
  font: 400 var(--fs-label)/1.5 var(--font-mono);
}

.development-notice::before {
  display: inline-block;
  width: 7px;
  height: 7px;
  margin-right: 8px;
  background: var(--amber);
  content: "";
  vertical-align: 0.05em;
}

/* ---------- Responsive ---------- */

@media (max-width: 1280px) {
  .page-heading {
    align-items: stretch;
    flex-direction: column;
  }

  .report-filters {
    grid-template-columns: minmax(200px, 1fr) minmax(132px, 180px);
  }

  .filter-bar {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .create-bar {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 960px) {
  /* Rows keep their content height, so a short page does not stretch the
     phone bar. */
  .control-shell {
    align-content: start;
    grid-template-columns: minmax(0, 1fr);
  }

  .side-rail {
    position: fixed;
    left: 0;
    width: min(272px, calc(100vw - 48px));
    transform: translateX(-105%);
    transition: transform 200ms var(--ease);
  }

  .side-rail.is-open {
    transform: translateX(0);
    box-shadow: var(--shadow-lg);
  }

  /* The phone bar sits in the page flow and stays at the top while the page
     scrolls. */
  .mobile-bar {
    position: sticky;
    z-index: 70;
    top: 0;
    display: flex;
    min-height: 60px;
    align-items: center;
    gap: 12px;
    padding: 8px 16px;
    border-bottom: 1px solid var(--border);
    background: var(--bg);
  }

  .mobile-bar .sidebar-mobile-toggle {
    display: grid;
    flex: none;
  }

  /* A shell without the phone bar keeps a floating menu button. */
  .control-shell > .sidebar-mobile-toggle {
    position: fixed;
    z-index: 70;
    top: 12px;
    left: 12px;
    display: grid;
  }

  body:has(> .development-notice) .control-shell > .sidebar-mobile-toggle {
    top: 46px;
  }

  .sidebar-backdrop:not([hidden]) {
    position: fixed;
    z-index: 75;
    inset: 0;
    display: block;
    width: 100%;
    height: 100%;
    padding: 0;
    border: 0;
    background: color-mix(in srgb, var(--bg) 72%, transparent);
  }

  body.sidebar-is-open {
    overflow: hidden;
  }

  .control-main {
    padding: 66px 18px 44px;
  }

  .control-shell:has(> .mobile-bar) .control-main {
    padding-top: 24px;
  }

  .control-main [id] {
    scroll-margin-top: 80px;
  }

  .metric-strip {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 620px) {
  .control-main {
    padding: 62px 16px 36px;
  }

  .control-shell:has(> .mobile-bar) .control-main {
    padding-top: 20px;
  }

  .page-heading {
    gap: 16px;
    margin-bottom: 16px;
  }

  .page-actions {
    justify-content: flex-start;
  }

  .report-filters {
    grid-template-columns: minmax(0, 1.35fr) minmax(0, 0.9fr);
  }

  .filter-bar,
  .create-bar {
    grid-template-columns: minmax(0, 1fr);
    padding: 12px;
  }

  .metric-strip {
    gap: 12px;
  }

  .metric-item {
    padding: 14px;
  }

  .metric-item strong {
    margin-top: 12px;
    font-size: clamp(20px, 6.5vw, 24px);
  }

  .surface-heading,
  .card-heading {
    align-items: flex-start;
    padding: 14px 14px 8px;
  }

  .control-table th,
  .control-table td {
    padding-right: 12px;
    padding-left: 12px;
  }

  .login-page {
    padding: 16px;
    align-items: start;
  }

  .login-intro {
    padding: 22px 22px 0;
  }

  .login-form-panel {
    padding: 22px 22px 26px;
  }
}

@media (max-width: 460px) {
  .metric-strip {
    grid-template-columns: minmax(0, 1fr);
  }

  .metric-item {
    padding: 12px;
  }

  .metric-item strong {
    font-size: 24px;
  }

  .metric-item:has(> .metric-sparkline) {
    grid-template-columns: minmax(0, 1fr);
  }

  .metric-item > .metric-sparkline {
    display: none;
  }

  .report-filters {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* Touch targets and form text remain usable without enlarging dense tables.
   Fields you type in use 16 px so phones do not zoom in on them. Selects
   keep the 12 px mono value. */
@media (max-width: 720px) {
  .primary-button,
  .secondary-button,
  .danger-button,
  .ghost-button,
  .side-icon-button,
  .sidebar-mobile-toggle {
    min-height: 44px;
  }

  .side-icon-button,
  .sidebar-mobile-toggle {
    min-width: 44px;
  }

  :is(input.control-input, textarea.control-textarea, .control-main textarea, .control-main input:not([type="checkbox"], [type="radio"], [type="range"], [type="hidden"])):not(.verification-code) {
    font-size: 16px;
  }

  .login-page {
    min-height: 100svh;
  }
}

@media print {
  .mobile-bar {
    display: none !important;
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    scroll-behavior: auto !important;
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }
}

@media screen {
  .control-input,
  .control-select,
  .control-main select,
  .control-main input:not([type="checkbox"], [type="radio"], [type="range"], [type="hidden"]) {
    min-height: 38px;
  }
}

@media (pointer: coarse) {
  .side-nav a,
  .primary-button,
  .secondary-button,
  .ghost-button,
  .control-input,
  .control-select {
    min-height: 44px;
  }
}

@media (max-width: 720px) {
  .control-input,
  .control-select,
  .control-main select,
  .control-main input:not([type="checkbox"], [type="radio"], [type="range"], [type="hidden"]) {
    min-height: 44px;
  }
}
