/* Lens component layer.
   New classes only -- global overrides of Tabler's own behaviour belong in
   app.css. Every --lens-* value read here is emitted per-theme by
   templates/theme.css.twig from src/Theme/*; nothing in this file may define one
   or branch on which theme is active. See docs/design/theming.md, and
   docs/design/lens-ledger.md for the Ledger rationale specifically. */

/* Every figure in the product. Tabular numerals are the reason a column of
   currency lines up; proportional digits make it ragged. Neither Bootstrap nor
   Tabler has a utility for this, which is the only reason it is a class. */
.lens-num {
  font-variant-numeric: tabular-nums;
}

/* ---- Classes this file deliberately does NOT define ---------------------
   Each would restate something Tabler or Bootstrap already ships. Compose the
   existing class instead:

     micro-label   -> .subheader        (Tabler's, retuned to Ledger in app.css;
                                         .datagrid-title inside a datagrid)
     mono figure   -> .font-monospace .lens-num
     rising delta  -> .text-green .lens-num
     falling delta -> .text-danger .lens-num
     filter        -> .btn              (plain -- never .btn-primary, see
                                         "Hierarchy" in the design doc)

   The design rules they carried are not lost; they live in
   docs/design/lens-ledger.md, which is where a rule belongs once the thing
   enforcing it is a class someone else maintains. */

/* ---- Seeded avatar ------------------------------------------------------
   The fill comes from user_color(), which is seeded off the entity id and is
   therefore the SAME colour in both themes -- deliberately, so a person keeps
   their colour when you flip the OS theme. A theme-invariant background needs a
   theme-invariant foreground, so this cannot be Tabler's `text-light`: that
   resolves to --tblr-light and inverts in dark, dropping the initials to 2.9:1
   against their own disc.

   The literal is the same exception login_hero.css takes, and for the same
   reason -- this is a brand surface, not a page surface, so it does not follow
   the palette. Every fill user_color() can return is picked from
   Globals::BRANDING['avatar_palette'] and clears 4.5:1 against this label; that
   is the constraint on adding one there. See "Four ways to break it" in
   docs/design/lens-ledger.md. */
.lens-avatar {
  color: #F7F9FC;
}

/* ---- Status chips -------------------------------------------------------
   There is no .lens-chip class. The chip IS <twig:badge> -- Tabler's .badge,
   squared off by the radius reset and padded to the comp's 8px in app.css.
   A parallel class here would only mean two ways to draw the same thing.

   The comp's chip pairs are not carried as tokens either: they describe a fill
   nothing draws. See "Status pairs" in docs/design/lens-ledger.md. */

/* ---- Penetration bars ---------------------------------------------------
   A MODIFIER on Tabler's .progress, not a bar of our own. Tabler already gives
   us the track, the fill, the geometry and the width transition; the one thing
   it has no concept of is a target, so that is all this adds -- the tick, and
   the two fills that say which side of it we are on.

   Set --lens-target as a percentage to place the tick; add .is-at-target once
   the value has reached it. Recolours by setting Tabler's own bar variable, so
   .progress-bar itself needs no class. */
.progress-target {
  --tblr-progress-bg: var(--lens-progress-track);
  /* progress-fill-* rather than chart-* : these are DOM bars, so a theme may
     hand over a gradient here. The chart tokens have to stay flat colours
     because chart_theme.js paints them onto a canvas. */
  --tblr-progress-bar-bg: var(--lens-progress-fill-below);
}

.progress-target.is-at-target {
  --tblr-progress-bar-bg: var(--lens-progress-fill-at);
}

/* Tabler's .progress is already position:relative and overflow:visible, which
   is what lets the tick overhang the track without either being declared here. */
.progress-target::after {
  content: "";
  position: absolute;
  left: var(--lens-target, 50%);
  top: -3px;
  bottom: -3px;
  width: 2px;
  background: var(--lens-chart-target-line);
}

/* ---- Datagrid -----------------------------------------------------------
   Tabler's key/value grid is where most Lens figures actually land (the deal
   summary, the drilldowns). The title is already uppercased by the component,
   so it only needs the label treatment; the content gets tabular numerals,
   which is a no-op on the rows that hold text. */
.datagrid-title {
  font-size: var(--lens-font-size-h6);
  font-weight: 600;
  letter-spacing: var(--lens-thead-tracking);
  color: var(--lens-thead-color);
}

.datagrid-content {
  font-variant-numeric: tabular-nums;
}

/* ---- Stat tile ----------------------------------------------------------
   Label above, figure below, delta beneath that. The figure is the only
   thing on the tile allowed to be large. */
.lens-stat-value {
  font-size: var(--lens-stat-size);
  font-family: var(--lens-stat-family);
  font-weight: 600;
  letter-spacing: var(--lens-stat-tracking);
  /* 1, not 1.1 — both comps declare line-height: 1 on the tile figure. */
  line-height: 1;
  color: var(--tblr-gray-900);
  font-variant-numeric: tabular-nums;
}

/* ---- One-time-code boxes ------------------------------------------------
   public/auth/2fa.html.twig. A fixed square rather than a `.col` fraction: each
   box holds exactly one digit, so there is nothing to gain from growing with the
   viewport -- at container width they come out visibly landscape.

   Sized directly rather than with `px-3 py-3`: under border-box those utilities
   would only eat into the digit's room without changing the box. */
.lens-code-input {
  width: 3.375rem;   /* 54px */
  height: 3.375rem;
  padding: 0;
}

/* ---- Page header --------------------------------------------------------
   Title and meta, and NO rule of its own. Every section below opens with its
   own border-top, so a rule here just adds a second line 16px above the first
   one -- two parallel rules with nothing between them. The heading is set off
   by size and space; the first card's rule is what closes it.

   Deliberately not Tabler's `.page-header`: that class is already in use as a
   card header (components/dealer/Settings.html.twig, with an h2 title), where a
   34px title would be wrong.

   Stacked, not inline: the title owns its own line and the meta sits under it. */
.lens-page-header {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
  /* The air is padding here, not a margin on the column: .row pulls its
     children up by --bs-gutter-y, so an `mt-*` utility on the col is cancelled
     out and the title ends up 8px under the toolbar. */
  padding-top: 2rem;
  padding-bottom: 0.875rem;
}

/* The h1 step, once per page. Headings tighten as they grow, hence -0.02em. */
.lens-page-header__title {
  margin: 0;
  font-size: var(--lens-font-size-h1);
  /* Weight and tracking are per-theme, not fixed: Ledger's comp sets the title at
     34px/400/-0.01em and lets the size carry it, while Air runs 30px/600/-0.02em. */
  font-weight: var(--lens-h1-weight);
  letter-spacing: var(--lens-h1-tracking);
  line-height: 1.15;
  color: var(--tblr-gray-900);
}

/* What the page is about, before any figure on it says so. Its own line under
   the title, tertiary, so it reads as an annotation and never as a second
   heading competing with the one above it. */
.lens-page-header__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem;
  color: var(--lens-tertiary);
  font-variant-numeric: tabular-nums;
}

/* Typographic separator between inline entries -- the comp's 3px disc. Named for
   what it is rather than where it started (the page header's meta line), since
   nothing about it is specific to that row.

   NOT Tabler's .status-dot, which is the same shape and nothing else: that one is
   a status indicator driven by --tblr-status-color and the .status component, so
   reusing it here would mean overriding two of a component's tokens inline, at
   every call site, to say something that is not a status.

   A real element rather than generated content on the following entry. A
   `content: "·"` puts a character inside whatever box it is attached to -- on a
   chip the dot picks up the chip's tint and padding -- and generated text cannot
   be selected while still being announced by some screen readers. A markup
   element also means the separator is emitted only in front of an entry that
   actually renders, so a conditional entry cannot leave a dangling dot behind. */
.lens-typography-dot {
  /* The meta line is baseline-aligned for its text; a 3px disc has no baseline
     worth aligning, so it centres against the line instead. */
  align-self: center;
  flex: none;
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: var(--tblr-border-strong);
}

/* ---- Splash layout ------------------------------------------------------
   A single card floating over the login hero (layouts/splash-card.html.twig).
   The card is a genuine floating surface -- above the sheet rather than part
   of it -- so unlike a section it keeps a border and a fill. Square, like
   everything else. */
.splash {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100dvh;
  padding: 2rem 1rem;
}

.splash__backdrop {
  position: absolute;
  inset: 0;
  overflow: hidden;
}

.splash__card {
  position: relative;
  width: 100%;
  max-width: 30rem;
  padding: 2rem;
  background: var(--lens-panel-bg);
  border: var(--lens-panel-border);
  border-radius: var(--lens-radius-surface);
  box-shadow: var(--lens-panel-shadow);
}

/* The height goes on the image: the lockup is an SVG with a 1393x424
   intrinsic size, so constraining the anchor does nothing. */
.splash__lockup {
  height: 3.5em;
}
