/* ============================================================================
   rocket-ship — component layer
   Consumes design/tokens/tokens.css. Contains ZERO hardcoded colour values.
   Every page in mockup/ links tokens.css first, then this file.
   ========================================================================== */

/* ==========================================================================
   ICONS — one sprite, geometric, 1.5px stroke. Industrial, not rounded-cute.
   ========================================================================== */
.icon {
  inline-size: 1.25em; block-size: 1.25em;
  fill: none; stroke: currentColor; stroke-width: 1.5;
  stroke-linecap: square; stroke-linejoin: miter;
  flex: none;
}
.icon--sm { inline-size: 1em; block-size: 1em; }
.icon--lg { inline-size: 1.5em; block-size: 1.5em; }

/* ==========================================================================
   APP SHELL
   Desktop ≥1024: fixed sidebar + topbar.
   Below 1024:    topbar stays, sidebar becomes a bottom tab bar.
   Nothing is removed — only relocated.
   ========================================================================== */
.app {
  min-block-size: 100dvh;
  display: grid;
  /* minmax(0,1fr), not 1fr: a bare 1fr track floors at the widest child's
     min-content, which is how one long unbreakable string ends up scrolling
     the whole app sideways on a phone. */
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: var(--hq-topbar-h) 1fr auto;
  grid-template-areas: "top" "main" "tabs";
  background: var(--color-surface-page);
}
@media (min-width: 1024px) {
  .app {
    grid-template-columns: var(--hq-sidebar-w) minmax(0, 1fr);
    grid-template-rows: var(--hq-topbar-h) 1fr;
    grid-template-areas: "side top" "side main";
  }
}

/* --- topbar -------------------------------------------------------------- */
.topbar {
  grid-area: top;
  display: flex; align-items: center; gap: var(--space-xs);
  padding-inline: var(--space-sm);
  background: var(--color-surface-raised);
  border-block-end: 1px solid var(--color-border-hairline);
  position: sticky; inset-block-start: 0; z-index: var(--z-sticky);
}
.topbar__title {
  font-family: var(--font-display);
  font-size: var(--text-lg); font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-tight);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.topbar__spacer { margin-inline-start: auto; }
.topbar__mark { color: var(--color-brand); inline-size: 26px; flex: none; }
@media (min-width: 1024px) { .topbar__mark { display: none; } }

/* --- search -------------------------------------------------------------- */
.search {
  display: none;
  align-items: center; gap: var(--space-2xs);
  block-size: var(--control-h-md);
  inline-size: min(22rem, 30vw);
  padding-inline: var(--space-xs);
  background: var(--color-surface-sunken);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  color: var(--color-text-muted);
  font-size: var(--text-sm);
}
@media (min-width: 768px) { .search { display: flex; } }
.search kbd {
  margin-inline-start: auto;
  font-family: var(--font-mono); font-size: var(--text-2xs);
  padding: 2px 5px; border-radius: var(--radius-xs);
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border-divider);
}

/* --- sidebar ------------------------------------------------------------- */
.side {
  grid-area: side;
  display: none;
  flex-direction: column;
  background: var(--color-surface-raised);
  border-inline-end: 1px solid var(--color-border-hairline);
  position: sticky; inset-block-start: 0; block-size: 100dvh;
}
@media (min-width: 1024px) { .side { display: flex; } }

.side__brand {
  display: flex; align-items: center; gap: var(--space-2xs);
  block-size: var(--hq-topbar-h);
  padding-inline: var(--space-sm);
  border-block-end: 1px solid var(--color-border-hairline);
  color: var(--color-brand);
}
.side__brand span {
  font-family: var(--font-display); font-weight: var(--weight-medium);
  font-size: var(--text-base); letter-spacing: var(--tracking-tight);
  color: var(--color-text-primary);
}
.side__nav { padding: var(--space-xs) var(--space-2xs); overflow-y: auto; flex: 1; }
.side__group { margin-block-end: var(--space-md); }
.side__group > .label-metric { padding-inline: var(--space-2xs); display: block; margin-block-end: var(--space-3xs); }

/* Nav item. Active state is surface + colour + weight. No edge accent: the
   selected tint already says "this one", and a badge beside it says it twice. */
.nav-item {
  position: relative;
  display: flex; align-items: center; gap: var(--space-2xs);
  block-size: var(--control-h-md);
  padding-inline: var(--space-2xs);
  border-radius: var(--radius-sm);
  color: var(--color-text-secondary);
  font-size: var(--text-sm); text-decoration: none;
  transition: background var(--duration-instant) var(--ease-out-quint),
              color var(--duration-instant) var(--ease-out-quint);
}
.nav-item:hover { background: var(--color-hover-wash); color: var(--color-text-primary); }
.nav-item[aria-current] {
  background: var(--color-selected);
  color: var(--color-brand-text);
  font-weight: var(--weight-medium);
}
.nav-item__count {
  margin-inline-start: auto;
  font-family: var(--font-mono); font-size: var(--text-2xs);
  font-variant-numeric: tabular-nums;
  color: var(--color-text-muted);
}
.nav-item[aria-current] .nav-item__count { color: var(--color-brand-text); }

.side__foot {
  border-block-start: 1px solid var(--color-border-hairline);
  padding: var(--space-2xs);
}

/* --- bottom tab bar (below 1024) ----------------------------------------- */
.tabbar {
  grid-area: tabs;
  display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
  block-size: var(--hq-tabbar-h);
  background: var(--color-surface-raised);
  border-block-start: 1px solid var(--color-border-hairline);
  position: sticky; inset-block-end: 0; z-index: var(--z-sticky);
  padding-block-end: env(safe-area-inset-bottom);
}
@media (min-width: 1024px) { .tabbar { display: none; } }
.tab {
  position: relative;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 3px;
  color: var(--color-text-muted); text-decoration: none;
  font-size: 10px; font-weight: var(--weight-medium);
  min-block-size: 44px;
}
.tab[aria-current] { color: var(--color-brand-text); }
.tab[aria-current]::before {
  content: "";
  position: absolute; inset-block-start: 0; inset-inline: 28%;
  block-size: 3px; background: var(--color-brand);
}

/* --- main ---------------------------------------------------------------- */
.main {
  grid-area: main;
  min-inline-size: 0;
  padding: var(--space-sm);
  display: flex; flex-direction: column; gap: var(--space-md);
}
@media (min-width: 768px)  { .main { padding: var(--space-md); } }
@media (min-width: 1440px) { .main { padding: var(--space-md) var(--space-lg); } }

/* ==========================================================================
   SECTION HEADER + WAYBILL — signature #2
   ========================================================================== */
.sec {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: var(--space-sm);
  padding-block-end: var(--space-2xs);
  border-block-end: 1px solid var(--color-border-hairline);
}
.sec h2 {
  font-family: var(--font-display);
  font-size: var(--text-xl); font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-tight);
}
.sec h3 { font-size: var(--text-lg); }
.sec p { font-size: var(--text-sm); color: var(--color-text-muted); margin: 2px 0 0; }

.waybill {
  display: flex; gap: var(--space-md);
  font-family: var(--font-mono); font-size: var(--text-2xs);
  letter-spacing: var(--tracking-label); text-transform: uppercase;
  color: var(--color-text-muted);
  line-height: 1.5;
}
.waybill > div { white-space: nowrap; }
.waybill b {
  display: block;
  font-family: var(--font-mono); font-size: var(--text-lg);
  font-weight: var(--weight-medium); font-variant-numeric: tabular-nums;
  letter-spacing: var(--tracking-normal);
  color: var(--color-text-primary);
}
.waybill--right { text-align: right; }
@media (max-width: 767px) { .waybill { display: none; } }

/* ==========================================================================
   SURFACES — hairline panels. No shadows. No nesting.
   ========================================================================== */
.panel {
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border-hairline);
  border-radius: var(--card-radius);
  overflow: clip;
}
.panel__head {
  display: flex; align-items: center; gap: var(--space-2xs); flex-wrap: wrap;
  padding: var(--space-xs) var(--space-sm);
  border-block-end: 1px solid var(--color-border-divider);
}
.panel__head h3 { font-size: var(--text-base); font-weight: var(--weight-semibold); font-family: var(--font-ui); }
.panel__body { padding: var(--space-sm); }
.panel__foot {
  padding: var(--space-xs) var(--space-sm);
  border-block-start: 1px solid var(--color-border-divider);
  background: var(--color-surface-sunken);
}

.grid { display: grid; gap: var(--space-sm); }
.grid--auto { grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr)); }
.grid--2 { grid-template-columns: minmax(0, 1fr); }
.grid--3 { grid-template-columns: minmax(0, 1fr); }
@media (min-width: 768px)  { .grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1024px) { .grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
/* Columns sit at their natural height; a short aside must not stretch the
   main panel into a field of empty surface. */
.grid--main-aside { grid-template-columns: minmax(0, 1fr); align-items: start; }
@media (min-width: 1024px) { .grid--main-aside { grid-template-columns: minmax(0,1.9fr) minmax(0,1fr); } }

/* Table-led page. A payroll or KPI table carries 7–8 columns of figures and
   does not fit in two-thirds of 1440px — it ends up scrolling sideways inside
   its own panel, which is the worst of both worlds. Here the data panel takes
   the full width and its supporting panels flow underneath. */
.grid--table-led { grid-template-columns: minmax(0, 1fr); align-items: start; }
@media (min-width: 1024px) {
  .grid--table-led > .stack:last-child {
    display: grid; gap: var(--space-sm); align-items: start;
    grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
  }
}

.stack { display: flex; flex-direction: column; gap: var(--space-sm); }
.stack--xs { gap: var(--space-2xs); }
.row { display: flex; align-items: center; gap: var(--space-2xs); flex-wrap: wrap; }
.row--tight { gap: var(--space-3xs); }
.push { margin-inline-start: auto; }

/* ==========================================================================
   CONTROLS
   ========================================================================== */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--space-3xs);
  block-size: var(--control-h-lg);
  padding-inline: var(--space-sm);
  border: var(--control-border-w) solid transparent;
  border-radius: var(--control-radius);
  font: inherit; font-size: var(--text-sm); font-weight: var(--weight-medium);
  text-decoration: none; cursor: pointer; white-space: nowrap;
  transition: background var(--duration-instant) var(--ease-out-quint),
              border-color var(--duration-instant) var(--ease-out-quint);
}
@media (min-width: 1024px) { .btn { block-size: var(--control-h-md); } }
.btn--xl { block-size: var(--control-h-xl); font-size: var(--text-md); padding-inline: var(--space-md); }
/* 32px is a desktop-table size. On a touch viewport every button, small
   variant included, still has to clear the 44px floor. */
.btn--sm { block-size: var(--control-h-lg); font-size: var(--text-xs); padding-inline: var(--space-xs); }
@media (min-width: 1024px) {
  .btn--sm { block-size: var(--control-h-sm); padding-inline: var(--space-2xs); }
}
.btn--block { inline-size: 100%; }

.btn--primary { background: var(--color-brand); color: var(--color-text-on-brand); }
.btn--primary:hover { background: var(--color-brand-hover); }
.btn--secondary {
  background: var(--color-surface-raised); color: var(--color-text-primary);
  border-color: var(--color-border-hairline);
}
.btn--secondary:hover { background: var(--color-hover-wash); }
.btn--ghost { background: transparent; color: var(--color-text-secondary); }
.btn--ghost:hover { background: var(--color-hover-wash); color: var(--color-text-primary); }
.btn--danger { background: var(--color-danger-dot); color: var(--rs-neutral-0); }
.btn--icon { inline-size: var(--control-h-lg); padding: 0; }
@media (min-width: 1024px) { .btn--icon { inline-size: var(--control-h-md); } }
.btn[disabled], .btn[aria-disabled="true"] {
  background: var(--color-surface-sunken); color: var(--color-text-disabled);
  border-color: var(--color-border-hairline); cursor: not-allowed;
}

/* Google sign-in. Brand-neutral by requirement — Google's mark must not be
   recoloured, so this button stays on a white surface in both themes. */
.btn--google {
  background: var(--rs-neutral-0); color: var(--rs-neutral-900);
  border-color: var(--rs-neutral-300);
}
.btn--google:hover { background: var(--rs-neutral-100); }

.field label, .field > .label {
  display: block;
  font-size: var(--field-label-size); font-weight: var(--weight-medium);
  margin-block-end: 5px;
}
.input, .select, .textarea {
  inline-size: 100%;
  block-size: var(--field-h);
  padding-inline: var(--space-xs);
  background: var(--color-surface-raised);
  border: 1px solid var(--color-border-hairline);
  border-radius: var(--field-radius);
  color: var(--color-text-primary);
  font: inherit; font-size: var(--text-md);
  display: flex; align-items: center;
}
@media (min-width: 1024px) { .input, .select, .textarea { font-size: var(--text-sm); } }
.textarea { block-size: auto; min-block-size: 5rem; padding-block: var(--space-2xs); align-items: flex-start; }
.input--placeholder { color: var(--color-text-disabled); }
.input--error { border-color: var(--color-danger-dot); }
.input--focus { border-color: var(--color-brand); outline: 2px solid var(--color-focus-ring); outline-offset: 1px; }
.input--readonly { background: var(--color-surface-sunken); color: var(--color-text-secondary); }
.field .help { font-size: var(--text-xs); color: var(--color-text-muted); margin-block-start: 5px; max-inline-size: 46ch; }
.field .err { font-size: var(--text-xs); color: var(--color-danger-fg); margin-block-start: 5px; }
.field .prefix { color: var(--color-text-muted); margin-inline-end: var(--space-3xs); font-family: var(--font-mono); font-size: var(--text-xs); }

.switch {
  inline-size: 40px; block-size: 24px; flex: none;
  border-radius: var(--radius-full);
  background: var(--color-border-strong);
  position: relative;
}
.switch::after {
  content: ""; position: absolute; inset-block-start: 3px; inset-inline-start: 3px;
  inline-size: 18px; block-size: 18px; border-radius: 50%;
  background: var(--rs-neutral-0);
}
.switch[aria-checked="true"] { background: var(--color-brand); }
.switch[aria-checked="true"]::after { inset-inline-start: 19px; }

.checkbox {
  inline-size: 20px; block-size: 20px; flex: none;
  border: 1.5px solid var(--color-border-strong);
  border-radius: var(--radius-xs);
  display: grid; place-items: center;
  color: transparent;
}
.checkbox[aria-checked="true"] {
  background: var(--color-brand); border-color: var(--color-brand);
  color: var(--color-text-on-brand);
}

/* ==========================================================================
   BADGES
   ========================================================================== */
.badge {
  display: inline-flex; align-items: center; gap: 5px;
  block-size: var(--badge-h); padding-inline: var(--badge-px);
  border-radius: var(--badge-radius);
  font-family: var(--font-mono); font-size: var(--text-2xs);
  font-weight: var(--weight-medium); letter-spacing: var(--tracking-label);
  text-transform: uppercase; white-space: nowrap;
}
.badge i { inline-size: 6px; block-size: 6px; border-radius: 50%; flex: none; }
.badge--success { background: var(--color-success-bg); color: var(--color-success-fg); }
.badge--success i { background: var(--color-success-dot); }
.badge--warning { background: var(--color-warning-bg); color: var(--color-warning-fg); }
.badge--warning i { background: var(--color-warning-dot); }
.badge--danger  { background: var(--color-danger-bg);  color: var(--color-danger-fg); }
.badge--danger i { background: var(--color-danger-dot); }
.badge--info    { background: var(--color-info-bg);    color: var(--color-info-fg); }
.badge--info i  { background: var(--color-info-dot); }
.badge--neutral { background: var(--color-surface-sunken); color: var(--color-text-muted); }
/* No dot. A neutral badge is a classification (DRAFT, SIAP, HARI KERJA), not a
   live state, and a grey dot on a grey badge carries nothing. The markup keeps
   its empty <i> so a badge can change severity without a markup edit. */
.badge--neutral i { display: none; }
/* Usage law: live = happening right now. One per viewport. */
.badge--live { background: var(--color-live); color: var(--color-live-on); }
.badge--live i { background: var(--color-live-on); }
/* The only perpetual animation in the system. It is motivated: hi-viz means
   happening right now, and a still dot cannot say "right now". It still has to
   stop for anyone who asked motion to stop. */
@media (prefers-reduced-motion: no-preference) {
  .badge--live i { animation: pulse 1.8s var(--ease-in-out) infinite; }
}
@keyframes pulse { 50% { opacity: 0.25; } }

.avatar {
  inline-size: 32px; block-size: 32px; flex: none;
  border-radius: var(--radius-full);
  background: var(--color-brand-subtle);
  color: var(--color-brand-text);
  display: grid; place-items: center;
  font-size: var(--text-xs); font-weight: var(--weight-semibold);
  letter-spacing: 0.02em;
}
.avatar--lg { inline-size: 48px; block-size: 48px; font-size: var(--text-base); }
.avatar--sm { inline-size: 24px; block-size: 24px; font-size: 10px; }

/* ==========================================================================
   DATA — table on desktop, record list on mobile. Same fields, both times.
   ========================================================================== */
.tbl { inline-size: 100%; border-collapse: collapse; font-size: var(--text-sm); }
.tbl th {
  text-align: start;
  font-family: var(--font-mono); font-size: var(--text-2xs);
  font-weight: var(--weight-medium); letter-spacing: var(--tracking-label);
  text-transform: uppercase; color: var(--color-text-muted);
  padding: var(--space-2xs) var(--table-cell-px);
  border-block-end: 1px solid var(--color-border-hairline);
  white-space: nowrap;
  position: sticky; inset-block-start: 0; background: var(--color-surface-raised);
}
.tbl td {
  padding: var(--space-2xs) var(--table-cell-px);
  border-block-end: 1px solid var(--color-border-divider);
  block-size: var(--table-row-h);
  vertical-align: middle;
}
.tbl tbody tr:last-child td { border-block-end: none; }
.tbl tbody tr:hover td { background: var(--color-hover-wash); }
.tbl .num, .tbl [data-numeric] {
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  text-align: end; white-space: nowrap;
}
.tbl .mono, .tbl td .badge { white-space: nowrap; }
.tbl tr[aria-selected="true"] td { background: var(--color-selected); }
.tbl__wrap { overflow-x: auto; }
@media (max-width: 767px) { .desktop-only { display: none !important; } }
@media (min-width: 768px) { .mobile-only { display: none !important; } }

/* mobile record list */
.rec {
  display: flex; flex-direction: column; gap: 6px;
  padding: var(--space-xs) var(--space-sm);
  border-block-end: 1px solid var(--color-border-divider);
  position: relative;
}
.rec:last-child { border-block-end: none; }
.rec__top { display: flex; align-items: flex-start; gap: var(--space-2xs); }
.rec__title { font-weight: var(--weight-semibold); font-size: var(--text-base); line-height: 1.3; }
.rec__sub { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--color-text-muted); }
.rec__fields {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(96px, 100%), 1fr));
  gap: var(--space-2xs) var(--space-sm);
  margin-block-start: 2px;
}
.rec__fields > div > span {
  display: block;
  font-family: var(--font-mono); font-size: var(--text-2xs);
  letter-spacing: var(--tracking-label); text-transform: uppercase;
  color: var(--color-text-muted);
}
.rec__fields > div > b {
  font-family: var(--font-mono); font-size: var(--text-sm);
  font-variant-numeric: tabular-nums; font-weight: var(--weight-medium);
}
.rec[aria-selected="true"] { background: var(--color-selected); }

/* key/value pairs — the mono label/value costume from the brand book */
.kv { display: grid; gap: var(--space-2xs) var(--space-md); }
.kv--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.kv--3 { grid-template-columns: repeat(auto-fit, minmax(min(120px, 100%), 1fr)); }
.kv dt {
  font-family: var(--font-mono); font-size: var(--text-2xs);
  letter-spacing: var(--tracking-label); text-transform: uppercase;
  color: var(--color-text-muted);
}
.kv dd { margin: 2px 0 0; font-size: var(--text-sm); }
.kv dd.num { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.kv dd { overflow-wrap: anywhere; }

/* ==========================================================================
   TASKS
   ========================================================================== */
.task {
  display: flex; align-items: flex-start; gap: var(--space-2xs);
  padding: var(--space-2xs) var(--space-sm);
  border-block-end: 1px solid var(--color-border-divider);
  min-block-size: 52px;
}
.task:last-child { border-block-end: none; }
.task__body { flex: 1; min-inline-size: 0; }
.task__title { font-size: var(--text-sm); font-weight: var(--weight-medium); line-height: 1.35; }
.task__meta {
  display: flex; flex-wrap: wrap; gap: var(--space-2xs);
  font-family: var(--font-mono); font-size: var(--text-2xs);
  letter-spacing: var(--tracking-label); text-transform: uppercase;
  color: var(--color-text-muted);
  margin-block-start: 3px;
}
.task--done .task__title { color: var(--color-text-muted); text-decoration: line-through; }
.task__points {
  font-family: var(--font-mono); font-size: var(--text-xs);
  font-variant-numeric: tabular-nums; font-weight: var(--weight-medium);
  color: var(--color-text-secondary);
  padding: 2px 6px; border-radius: var(--radius-xs);
  background: var(--color-surface-sunken);
  flex: none;
}

/* ==========================================================================
   STEPS — horizontal rule with 23deg ticks
   ========================================================================== */
.steps { display: grid; gap: var(--space-sm); grid-template-columns: minmax(0, 1fr); }
@media (min-width: 768px) { .steps { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.step { padding-block-start: var(--space-sm); position: relative; }
/* The rule above a step is the whole device. A 2px brand segment marks where
   it starts, which is a rule doing its job, not an accent stuck on top. */
.step::before {
  content: ""; position: absolute; inset-block-start: 0; inset-inline: 0;
  block-size: 1px; background: var(--color-border-hairline);
}
.step::after {
  content: ""; position: absolute; inset-block-start: 0; inset-inline-start: 0;
  inline-size: 40px; block-size: 2px; background: var(--color-brand);
}
.step__n {
  font-family: var(--font-mono); font-size: var(--text-2xs);
  letter-spacing: var(--tracking-label); color: var(--color-brand-text);
  display: block; margin-block-end: 4px;
}

/* ==========================================================================
   PROGRESS — plain square fill. A progress bar is a measurement, and the
   signature belongs on markers, not on every coloured rectangle.
   ========================================================================== */
.bar {
  block-size: 6px; border-radius: 2px; overflow: clip;
  background: color-mix(in oklch, var(--color-border-strong) 45%, transparent);
}
.bar > span {
  display: block; block-size: 100%; background: var(--color-brand);
}
.bar--success > span { background: var(--color-success-dot); }
.bar--warning > span { background: var(--color-warning-dot); }

/* ==========================================================================
   SCORE — KPI meters. Shared by the KPI module and the employee file, so it
   lives here rather than being written twice.
   ========================================================================== */
.meter { position: relative; block-size: 8px; border-radius: 2px; overflow: clip;
  background: color-mix(in oklch, var(--color-border-strong) 45%, transparent); }
.meter > span {
  display: block; block-size: 100%; background: var(--color-brand);
  clip-path: polygon(0 0, 100% 0, calc(100% - 4px) 100%, 0 100%);
}
.meter--good > span { background: var(--color-success-dot); }
.meter--watch > span { background: var(--color-warning-dot); }
.meter--bad > span { background: var(--color-danger-dot); }
/* Target tick: a plain upright. A target is a measurement — it stays square
   so the eye can read the exact position against the fill. */
.meter__target {
  position: absolute; inset-block: -3px; inline-size: 2px;
  background: var(--color-text-primary);
}

.score-num {
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-weight: var(--weight-medium); letter-spacing: -0.02em;
}

.trend { font-family: var(--font-mono); font-size: var(--text-xs); white-space: nowrap; }
.trend--up { color: var(--color-success-fg); }
.trend--down { color: var(--color-danger-fg); }
.trend--flat { color: var(--color-text-muted); }

/* Step rail for a multi-stage process (payroll run). Reads as a checklist,
   not as a decorative wizard. */
.rail { display: flex; flex-direction: column; }
.rail__step { display: flex; gap: var(--space-2xs); padding-block: var(--space-2xs); align-items: flex-start; }
.rail__dot {
  inline-size: 20px; block-size: 20px; flex: none; border-radius: 50%;
  border: 1.5px solid var(--color-border-strong);
  display: grid; place-items: center; color: transparent;
  font-family: var(--font-mono); font-size: 11px;
}
.rail__step--done .rail__dot { background: var(--color-success-dot); border-color: var(--color-success-dot); color: var(--rs-neutral-0); }
.rail__step--now .rail__dot { border-color: var(--color-brand); color: var(--color-brand-text); }
.rail__step--now { font-weight: var(--weight-medium); }
.rail__step--todo { color: var(--color-text-muted); }

/* ==========================================================================
   SHEET / DRAWER — replaces modals
   ========================================================================== */
.sheet {
  position: fixed; inset-inline: 0; inset-block-end: 0; z-index: var(--z-overlay);
  background: var(--color-surface-overlay);
  border-start-start-radius: var(--sheet-radius);
  border-start-end-radius: var(--sheet-radius);
  box-shadow: var(--shadow-sheet);
  max-block-size: 88dvh; display: flex; flex-direction: column;
}
@media (min-width: 1024px) {
  .sheet {
    inset-block: 0; inset-inline-start: auto; inline-size: min(30rem, 42vw);
    border-radius: 0; border-inline-start: 1px solid var(--color-border-hairline);
    max-block-size: none;
  }
}
.sheet__grab {
  inline-size: 36px; block-size: 4px; border-radius: 2px;
  background: var(--color-border-strong);
  margin: var(--space-2xs) auto 0;
}
@media (min-width: 1024px) { .sheet__grab { display: none; } }
.sheet__head {
  display: flex; align-items: center; gap: var(--space-2xs);
  padding: var(--space-sm);
  border-block-end: 1px solid var(--color-border-divider);
}
.sheet__body { padding: var(--space-sm); overflow-y: auto; flex: 1; }
.sheet__foot {
  padding: var(--space-sm);
  border-block-start: 1px solid var(--color-border-divider);
  display: flex; gap: var(--space-2xs);
  padding-block-end: max(var(--space-sm), env(safe-area-inset-bottom));
}
.scrim { position: fixed; inset: 0; background: var(--color-scrim); z-index: var(--z-overlay); }

/* ==========================================================================
   CALLOUT — full border + tint. Never a side-stripe.
   ========================================================================== */
.callout {
  display: flex; gap: var(--space-2xs);
  padding: var(--space-xs);
  border-radius: var(--radius-sm);
  border: 1px solid;
  font-size: var(--text-sm);
}
.callout--info { background: var(--color-info-bg); border-color: var(--color-brand-subtle-border); color: var(--color-info-fg); }
.callout--warning { background: var(--color-warning-bg); border-color: var(--color-warning-dot); color: var(--color-warning-fg); }
.callout--danger { background: var(--color-danger-bg); border-color: var(--color-danger-dot); color: var(--color-danger-fg); }
.callout--success { background: var(--color-success-bg); border-color: var(--color-success-dot); color: var(--color-success-fg); }
.callout b { font-weight: var(--weight-semibold); }

/* ==========================================================================
   EMPTY STATE — teaches the screen, never "No data available"
   ========================================================================== */
.empty {
  padding: var(--space-xl) var(--space-sm);
  text-align: center; color: var(--color-text-muted);
  display: flex; flex-direction: column; align-items: center; gap: var(--space-2xs);
}
.empty h4 { font-size: var(--text-base); font-weight: var(--weight-semibold); color: var(--color-text-primary); }
.empty p { font-size: var(--text-sm); max-inline-size: 42ch; margin: 0; }

/* ==========================================================================
   TABS
   ========================================================================== */
/* A tab strip sharing a .row with action buttons must claim a full line of
   its own on a phone, otherwise the buttons squeeze it to a stub and the tab
   labels scroll out of reach. */
.tabs {
  display: flex; gap: var(--space-sm);
  border-block-end: 1px solid var(--color-border-hairline);
  overflow-x: auto; scrollbar-width: none;
  min-inline-size: min(100%, 20rem);
}
.tabs::-webkit-scrollbar { display: none; }
.tabs a {
  position: relative;
  display: inline-flex; align-items: center; gap: 6px;
  min-block-size: var(--control-h-lg);   /* tapped on a phone like any control */
  padding-block: var(--space-2xs);
  font-size: var(--text-sm); font-weight: var(--weight-medium);
  color: var(--color-text-muted); text-decoration: none; white-space: nowrap;
}
@media (min-width: 1024px) { .tabs a { min-block-size: 36px; } }
.tabs a[aria-current] { color: var(--color-text-primary); }
.tabs a[aria-current]::after {
  content: ""; position: absolute; inset-block-end: -1px; inset-inline: 0;
  block-size: 2px; background: var(--color-brand);
}

/* ==========================================================================
   MEDIA PLACEHOLDERS — mockup only, replaced by real assets at build
   ========================================================================== */
.ph {
  position: relative; overflow: clip;
  background: var(--color-surface-sunken);
  display: grid; place-items: center;
  color: var(--color-text-disabled);
  font-family: var(--font-mono); font-size: var(--text-2xs);
  letter-spacing: var(--tracking-label); text-transform: uppercase;
}
.ph--map {
  background-image:
    linear-gradient(var(--color-border-divider) 1px, transparent 1px),
    linear-gradient(90deg, var(--color-border-divider) 1px, transparent 1px);
  background-size: 28px 28px;
}
.ph--photo { background: var(--rs-neutral-800); color: var(--rs-neutral-500); }

/* ==========================================================================
   UTILITIES
   ========================================================================== */
.mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.muted { color: var(--color-text-muted); }
.small { font-size: var(--text-xs); }
.big-num {
  font-family: var(--font-mono); font-variant-numeric: tabular-nums;
  font-size: var(--text-2xl); font-weight: var(--weight-medium);
  letter-spacing: -0.02em; line-height: 1.1;
}
.rule { block-size: 1px; background: var(--color-border-hairline); border: 0; margin: 0; }
.sr-only {
  position: absolute; inline-size: 1px; block-size: 1px;
  padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

/* ==========================================================================
   FOCUS + SKIP LINK
   Appended last on purpose: a focus ring must outrank every component rule
   above it, and the cascade order in this file is load-bearing (see HANDOFF §8.3).

   --color-focus-ring was defined in tokens.css for both themes and was never
   consumed. Every interactive surface in site/ and hq/ inherited only the UA
   default ring, which is close to invisible on the dark hero and the blue
   contact band. WCAG 2.2 AA (2.4.7, 2.4.11) is a stated target.
   ========================================================================== */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
  border-radius: 1px;
}
/* On the ink and brand bands the blue ring sits too close to the ground.
   Pair it with a light halo so it reads on both. */
.hero :focus-visible,
.hdr :focus-visible,
.ftr :focus-visible,
.capacity :focus-visible,
#kontak :focus-visible {
  outline-color: var(--rs-neutral-0);
  outline-offset: 3px;
}

.skip-link {
  position: absolute; inset-inline-start: var(--space-sm); inset-block-start: -100%;
  z-index: calc(var(--z-sticky) + 1);
  background: var(--color-brand); color: var(--rs-neutral-0);
  font-family: var(--font-mono); font-size: var(--text-2xs);
  letter-spacing: var(--tracking-label); text-transform: uppercase;
  padding: 12px var(--space-sm); text-decoration: none;
}
.skip-link:focus-visible { inset-block-start: var(--space-2xs); }

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

/* hidden must win over component display rules (callout, row, ...) */
[hidden] { display: none !important; }
