/* ============================================================
   ACP IIT — Utilities
   ------------------------------------------------------------
   The vocabulary that replaces the 313 inline style="" attributes in
   views/. Every class here is token-driven, so a value set once in
   tokens.css propagates everywhere instead of being re-typed per element.

   Rule of thumb: if a declaration appeared inline three or more times
   across the templates, it earns a class here. Anything used once stays
   in that screen's own views/*.css.
   ============================================================ */

/* ── Flow ───────────────────────────────────────────────────── */

.row            { display: flex; align-items: center; }
.row-start      { display: flex; align-items: flex-start; }
.row-between    { display: flex; align-items: center; justify-content: space-between; }
.row-end        { display: flex; align-items: center; justify-content: flex-end; }
.row-wrap       { flex-wrap: wrap; }

.col            { display: flex; flex-direction: column; }
.col-center     { display: flex; flex-direction: column; align-items: center; }

.stack          { display: flex; flex-direction: column; gap: var(--s-3); }
.stack-tight    { display: flex; flex-direction: column; gap: var(--s-2); }
.stack-loose    { display: flex; flex-direction: column; gap: var(--s-4); }

.gap-1 { gap: var(--s-1); }
.gap-2 { gap: var(--s-2); }
.gap-3 { gap: var(--s-3); }
.gap-4 { gap: var(--s-4); }
.gap-5 { gap: var(--s-5); }

.flex-1     { flex: 1; }
.flex-none  { flex: 0 0 auto; }
.min-w-0    { min-width: 0; }
.min-h-0    { min-height: 0; }
.w-full     { width: 100%; }
.ml-auto    { margin-left: auto; }
.mt-auto    { margin-top: auto; }

/* Grid that fills the canvas instead of locking to a column count. The
   min track width is the knob each screen tunes via --col-min. */
.grid-auto {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(var(--col-min, 230px), 1fr));
    gap: var(--gap-grid);
}

/* ── Scroll containment ──────────────────────────────────────────
   A panel that scrolls its own body without letting the gesture escape
   to the page behind it. Paired with .min-h-0 on flex children, which
   is what makes nested flex scrolling actually work. */

.scroll-y {
    overflow-y: auto;
    overscroll-behavior: contain;
    min-height: 0;
}

.scroll-x {
    overflow-x: auto;
    overscroll-behavior-x: contain;
}

/* ── Text roles ───────────────────────────────────────────────
   These four cover essentially every text style the templates were
   spelling out inline. Note --fs-2xs (11px) is the floor: the old
   8.5-10px micro-labels all land here. */

.t-label {
    font-size: var(--fs-2xs);
    font-weight: var(--fw-bold);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--muted);
    line-height: var(--lh-tight);
}

.t-value {
    font-size: var(--fs-md);
    font-weight: var(--fw-bold);
    color: var(--text);
    line-height: var(--lh-tight);
}

.t-meta {
    font-size: var(--fs-xs);
    font-weight: var(--fw-normal);
    color: var(--muted);
    line-height: var(--lh-base);
}

.t-mono {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
}

.t-strong   { font-weight: var(--fw-bold); color: var(--text); }
.t-muted    { color: var(--muted); }
.t-subtle   { color: var(--subtle); }
.t-accent   { color: var(--accent); }
.t-ok       { color: var(--green); }
.t-warn     { color: var(--amber); }
.t-err      { color: var(--red); }
.t-info     { color: var(--blue); }

.t-xs { font-size: var(--fs-xs); }
.t-sm { font-size: var(--fs-sm); }
.t-md { font-size: var(--fs-md); }
.t-lg { font-size: var(--fs-lg); }
.t-xl { font-size: var(--fs-xl); }

.ta-l { text-align: left; }
.ta-c { text-align: center; }
.ta-r { text-align: right; }

/* One line, ellipsised. Requires a min-width:0 ancestor inside flex. */
.truncate {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
}

/* Numeric cell: right-aligned, mono, fixed-width digits. Every telemetry
   column and report figure uses this so decimal points line up. */
.num {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
    text-align: right;
    font-weight: var(--fw-medium);
}

/* ── Icon tile ────────────────────────────────────────────────
   The rounded square behind a Lucide glyph. Appeared ~20 times inline as
   width/height/border-radius/background/color/flex-centre. Colour comes
   from a modifier so it tracks the palette. */

.icon-tile {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 28px;
    height: 28px;
    border-radius: var(--r-sm);
    background: var(--accent-soft);
    color: var(--accent);
}

.icon-tile-sm { width: 22px; height: 22px; border-radius: var(--r-xs); }
.icon-tile-lg { width: 34px; height: 34px; border-radius: var(--r-md); }

.icon-tile.is-amber  { background: var(--amber-soft);  color: var(--amber); }
.icon-tile.is-green  { background: var(--green-soft);  color: var(--green); }
.icon-tile.is-red    { background: var(--red-soft);    color: var(--red); }
.icon-tile.is-blue   { background: var(--blue-soft);   color: var(--blue); }
.icon-tile.is-purple { background: var(--purple-soft); color: var(--purple); }
.icon-tile.is-plain  { background: var(--surface-2);   color: var(--muted); }

/* Consistent glyph sizing inside tiles and beside labels. Lucide renders
   an <svg> over the <i>, so both are targeted. */
.icon-tile > i,
.icon-tile > svg { width: 14px; height: 14px; }
.icon-tile-sm > i,
.icon-tile-sm > svg { width: 12px; height: 12px; }
.icon-tile-lg > i,
.icon-tile-lg > svg { width: 17px; height: 17px; }

.ico-xs > i, .ico-xs > svg { width: 12px; height: 12px; }
.ico-sm > i, .ico-sm > svg { width: 14px; height: 14px; }
.ico-md > i, .ico-md > svg { width: 16px; height: 16px; }
.ico-lg > i, .ico-lg > svg { width: 20px; height: 20px; }

/* ── Surfaces ─────────────────────────────────────────────────
   The inset panel used for grouped readouts (sensor rows, telemetry
   strips, KPI sub-tiles). */

.inset {
    background: var(--surface-2);
    border: 1px solid var(--border-subtle);
    border-radius: var(--r-md);
}

.inset-plain {
    background: var(--surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--r-md);
}

.divider-t { border-top: 1px solid var(--border-subtle); }
.divider-b { border-bottom: 1px solid var(--border-subtle); }

.pad-2 { padding: var(--s-2); }
.pad-3 { padding: var(--s-3); }
.pad-4 { padding: var(--s-4); }

/* ── Notice — the inline banner used for offline warnings, config hints
   and empty-state explanations. ─────────────────────────────── */

.notice {
    display: flex;
    align-items: flex-start;
    gap: var(--s-2);
    padding: var(--s-2) var(--s-3);
    border-radius: var(--r-md);
    font-size: var(--fs-xs);
    line-height: var(--lh-base);
    background: var(--surface-2);
    color: var(--muted);
    border: 1px solid var(--border-subtle);
}

.notice > i,
.notice > svg { width: 15px; height: 15px; flex-shrink: 0; margin-top: 1px; }

.notice.is-warn { background: var(--amber-soft); color: var(--amber); border-color: transparent; }
.notice.is-err  { background: var(--red-soft);   color: var(--red);   border-color: transparent; }
.notice.is-ok   { background: var(--green-soft); color: var(--green); border-color: transparent; }
.notice.is-info { background: var(--accent-soft); color: var(--accent); border-color: transparent; }

/* ── Visibility ───────────────────────────────────────────────── */

.hidden { display: none !important; }

/* Available to assistive tech, invisible on screen — used for the text
   half of status cues whose visual form is an icon or dot. */
.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;
}
