/* ============================================================================
   AddressGuard admin — design tokens and composition primitives.

   Polaris supplies the components, the colour system and the type ramp. This
   file supplies only what Polaris has no opinion about: page composition,
   spacing rhythm, and the four structures that must look identical on every
   screen — the status badge, the address block, the address comparison and the
   timeline.

   Deliberately NOT here: a parallel colour palette, custom buttons, custom
   inputs, bespoke card chrome. Those put a competing design language on top of
   Polaris, which is exactly what §55 warns against.
   ========================================================================= */

:root {
  /* Spacing — one scale, used everywhere. 4px base, so custom blocks line up
     with Polaris ones instead of sitting a pixel or two off. */
  --ag-1:  4px;
  --ag-2:  8px;
  --ag-3:  12px;
  --ag-4:  16px;
  --ag-5:  20px;
  --ag-6:  24px;
  --ag-8:  32px;
  --ag-10: 40px;

  /* Type — ONE ramp, matching Polaris's own steps. Nothing may use a size that
     is not on this list. */
  --ag-t-xs:  12px;
  --ag-t-sm:  13px;
  --ag-t-md:  14px;
  --ag-t-lg:  16px;
  --ag-t-xl:  20px;
  --ag-t-2xl: 24px;

  --ag-w-body:   450;
  --ag-w-med:    550;
  --ag-w-strong: 600;
  --ag-w-title:  650;

  /* Surfaces and text are DERIVED from Polaris rather than declared.
     Polaris owns the theme, and the merchant's admin may be light or dark
     independently of their OS preference. A hardcoded palette here produces
     light text on a white card the moment the two disagree, so everything is
     expressed relative to the inherited colour instead. */
  --ag-inset: color-mix(in srgb, currentColor 4%, transparent);
  --ag-hover: color-mix(in srgb, currentColor 6%, transparent);

  --ag-line:      color-mix(in srgb, currentColor 12%, transparent);
  --ag-line-firm: color-mix(in srgb, currentColor 26%, transparent);

  --ag-muted: color-mix(in srgb, currentColor 76%, transparent);
  /* 72%, not 60%. At 60 the small uppercase labels measured 3.5:1 against a
     white Polaris card, below the 4.5 that WCAG AA asks for body text (§99). */
  --ag-faint: color-mix(in srgb, currentColor 72%, transparent);

  /* Semantic colour (§56): green healthy, amber attention, red critical, blue
     informational — and never green or purple on a call to action.

     Each is the vivid hue MIXED WITH currentColor rather than a fixed value.
     That is what makes them survive a theme we cannot see: on a light admin
     currentColor is near-black, so the mix darkens and holds contrast against
     white; on a dark admin currentColor is near-white, so the same declaration
     lightens instead. A fixed hex that passes on white fails on black, and
     Polaris does not follow prefers-color-scheme — it is told the theme by App
     Bridge — so a media query could not have detected which one we are in. */
  --ag-good-hue: #2f9e6b;
  --ag-warn-hue: #b98200;
  --ag-bad-hue:  #e5484d;
  --ag-info-hue: #2d7ff9;

  /* 55%, measured rather than chosen: at 65% the amber and green badges came
     out at 4.19 and 4.29 against their own tinted backgrounds, just under the
     4.5 AA needs. More currentColor in the mix deepens them on a light admin
     and lifts them on a dark one, so the fix works in both directions. */
  --ag-good: color-mix(in srgb, var(--ag-good-hue) 55%, currentColor);
  --ag-warn: color-mix(in srgb, var(--ag-warn-hue) 55%, currentColor);
  --ag-bad:  color-mix(in srgb, var(--ag-bad-hue)  55%, currentColor);
  --ag-info: color-mix(in srgb, var(--ag-info-hue) 55%, currentColor);

  --ag-r-sm: 6px;
  --ag-r:    8px;
  --ag-r-lg: 12px;

  --ag-max: 1200px;
}

body { margin: 0; }

.ag-page { font-size: var(--ag-t-md); line-height: 1.5; max-width: var(--ag-max); margin: 0 auto; }

/* Every Polaris s-* element is display:contents, so a margin set on one is
   silently discarded by the browser. Spacing between them has to come from a
   gap on a real parent box — this is the single most common way a Polaris
   layout ends up looking cramped for no visible reason. */
.ag-stack { display: flex; flex-direction: column; gap: var(--ag-4); }
.ag-stack-sm { display: flex; flex-direction: column; gap: var(--ag-2); }
.ag-row { display: flex; flex-wrap: wrap; gap: var(--ag-3); align-items: center; }

/* ---------------------------------------------------------------------------
   Page header
   ------------------------------------------------------------------------ */

.ag-head { display: flex; gap: var(--ag-4); align-items: flex-start;
           justify-content: space-between; flex-wrap: wrap; margin: 0 0 var(--ag-5); }
.ag-head-main { min-width: 0; flex: 1 1 320px; }
.ag-head-back { display: inline-flex; align-items: center; gap: var(--ag-1);
                font-size: var(--ag-t-sm); color: var(--ag-muted);
                margin: 0 0 var(--ag-2); cursor: pointer;
                background: none; border: 0; padding: 0; font-family: inherit; }
.ag-head-back:hover { color: inherit; }
.ag-head-back:focus-visible { outline: 2px solid var(--ag-info); outline-offset: 2px; border-radius: var(--ag-r-sm); }
.ag-head-title { font-size: var(--ag-t-xl); line-height: 1.25; font-weight: var(--ag-w-title);
                 letter-spacing: -.01em; margin: 0; display: flex; align-items: center;
                 gap: var(--ag-3); flex-wrap: wrap; }
.ag-head-meta { display: flex; gap: var(--ag-2) var(--ag-4); align-items: center;
                flex-wrap: wrap; margin: var(--ag-2) 0 0;
                font-size: var(--ag-t-sm); color: var(--ag-muted); }
.ag-head-actions { display: flex; gap: var(--ag-2); align-items: center; flex-wrap: wrap; }

/* ---------------------------------------------------------------------------
   Status badges (§60) — one design, every screen, eleven states.

   Colour is never the only signal (§99): each badge carries a dot whose SHAPE
   differs by tone, so the three states remain distinguishable to a merchant
   who cannot separate the red from the amber.
   ------------------------------------------------------------------------ */

.ag-badge { display: inline-flex; align-items: center; gap: var(--ag-2);
            font-size: var(--ag-t-xs); font-weight: var(--ag-w-med);
            line-height: 1; padding: 5px 9px 5px 7px; border-radius: 999px;
            border: 1px solid var(--ag-line-firm); white-space: nowrap; }
.ag-badge::before { content: ''; width: 7px; height: 7px; flex: none;
                    background: currentColor; border-radius: 50%; }

.ag-badge-good     { color: var(--ag-good); border-color: color-mix(in srgb, var(--ag-good-hue) 40%, transparent);
                     background: color-mix(in srgb, var(--ag-good-hue) 10%, transparent); }
.ag-badge-warn     { color: var(--ag-warn); border-color: color-mix(in srgb, var(--ag-warn-hue) 40%, transparent);
                     background: color-mix(in srgb, var(--ag-warn-hue) 12%, transparent); }
/* Square dot, not round: the critical state stays distinct without colour. */
.ag-badge-bad      { color: var(--ag-bad); border-color: color-mix(in srgb, var(--ag-bad-hue) 45%, transparent);
                     background: color-mix(in srgb, var(--ag-bad-hue) 10%, transparent); }
.ag-badge-bad::before { border-radius: 1px; }
.ag-badge-info     { color: var(--ag-info); border-color: color-mix(in srgb, var(--ag-info-hue) 40%, transparent);
                     background: color-mix(in srgb, var(--ag-info-hue) 10%, transparent); }
/* Hollow dot: "we don't know" should not look like a verdict. */
.ag-badge-neutral  { color: var(--ag-muted); background: var(--ag-inset); }
.ag-badge-neutral::before { background: none; box-shadow: inset 0 0 0 1.5px currentColor; }

/* ---------------------------------------------------------------------------
   Risk banner — the first thing read on the detail screen (§20)
   ------------------------------------------------------------------------ */

.ag-risk { display: flex; gap: var(--ag-4); align-items: flex-start;
           padding: var(--ag-4); border-radius: var(--ag-r);
           border: 1px solid var(--ag-line-firm); }
.ag-risk-icon { flex: none; display: flex; width: 22px; height: 22px; margin-top: 1px; }
.ag-risk-body { min-width: 0; flex: 1; }
.ag-risk-title { font-size: var(--ag-t-lg); font-weight: var(--ag-w-strong); margin: 0; }
.ag-risk-text { margin: var(--ag-1) 0 0; color: var(--ag-muted); }
.ag-risk-meta { margin: var(--ag-3) 0 0; font-size: var(--ag-t-sm); color: var(--ag-faint);
                display: flex; gap: var(--ag-2) var(--ag-4); flex-wrap: wrap; }

.ag-risk-bad  { border-color: color-mix(in srgb, var(--ag-bad-hue) 45%, transparent);
                background: color-mix(in srgb, var(--ag-bad-hue) 7%, transparent); color: inherit; }
.ag-risk-bad  .ag-risk-icon { color: var(--ag-bad); }
.ag-risk-warn { border-color: color-mix(in srgb, var(--ag-warn-hue) 45%, transparent);
                background: color-mix(in srgb, var(--ag-warn-hue) 9%, transparent); }
.ag-risk-warn .ag-risk-icon { color: var(--ag-warn); }
.ag-risk-good { border-color: color-mix(in srgb, var(--ag-good-hue) 40%, transparent);
                background: color-mix(in srgb, var(--ag-good-hue) 8%, transparent); }
.ag-risk-good .ag-risk-icon { color: var(--ag-good); }
.ag-risk-neutral .ag-risk-icon { color: var(--ag-muted); }

/* ---------------------------------------------------------------------------
   Issue list (§22) — problem, why it matters, what to do
   ------------------------------------------------------------------------ */

.ag-issues { list-style: none; margin: 0; padding: 0;
             display: flex; flex-direction: column; gap: var(--ag-4); }
.ag-issue { display: grid; grid-template-columns: 20px 1fr; gap: var(--ag-3);
            align-items: start; }
.ag-issue-icon { display: flex; margin-top: 2px; }
.ag-issue-definite .ag-issue-icon { color: var(--ag-bad); }
.ag-issue-likely   .ag-issue-icon { color: var(--ag-warn); }
.ag-issue-potential,
.ag-issue-informational { }
.ag-issue-potential .ag-issue-icon,
.ag-issue-informational .ag-issue-icon { color: var(--ag-faint); }
.ag-issue-title { font-weight: var(--ag-w-med); margin: 0; }
.ag-issue-text  { margin: var(--ag-1) 0 0; color: var(--ag-muted); max-width: 62ch; }
.ag-issue-rec   { margin: var(--ag-2) 0 0; font-size: var(--ag-t-sm);
                  padding-left: var(--ag-3); border-left: 2px solid var(--ag-line-firm);
                  color: var(--ag-muted); max-width: 62ch; }

/* ---------------------------------------------------------------------------
   Address block and the comparison (§21, §59)

   The signature component. Addresses are read as blocks, not sentences, so
   they get a fixed line structure, tabular numerals and a measure tight enough
   that two of them can be compared without the eye tracking across the page.
   ------------------------------------------------------------------------ */

.ag-address { font-variant-numeric: tabular-nums; line-height: 1.5;
              margin: 0; max-width: 34ch; }
.ag-address-line { display: block; }
.ag-address-empty { color: var(--ag-faint); font-style: italic; }

.ag-compare { display: grid; gap: var(--ag-4);
              grid-template-columns: 1fr auto 1fr; align-items: stretch; }
.ag-compare-side { min-width: 0; padding: var(--ag-4); border-radius: var(--ag-r);
                   border: 1px solid var(--ag-line); background: var(--ag-inset); }
.ag-compare-suggested { border-color: color-mix(in srgb, var(--ag-info-hue) 35%, transparent);
                        background: color-mix(in srgb, var(--ag-info-hue) 6%, transparent); }
.ag-compare-label { font-size: var(--ag-t-xs); font-weight: var(--ag-w-strong);
                    letter-spacing: .04em; text-transform: uppercase;
                    color: var(--ag-faint); margin: 0 0 var(--ag-3); }
.ag-compare-arrow { display: flex; align-items: center; color: var(--ag-faint); }

/* Lines that differ are marked, and marked in two ways at once: a tint AND a
   leading +/~ glyph. Colour alone would leave a merchant who cannot see it
   unable to tell which line changed, which is the whole point of the panel. */
.ag-address-changed { background: color-mix(in srgb, var(--ag-info-hue) 14%, transparent);
                      border-radius: var(--ag-r-sm); padding: 1px var(--ag-2);
                      margin-inline-start: calc(var(--ag-2) * -1); }

.ag-changes { list-style: none; margin: var(--ag-4) 0 0; padding: 0;
              display: flex; flex-direction: column; gap: var(--ag-2);
              font-size: var(--ag-t-sm); }
.ag-change { display: flex; gap: var(--ag-2); align-items: baseline; }
.ag-change-mark { font-weight: var(--ag-w-strong); font-variant-numeric: tabular-nums;
                  width: 1ch; flex: none; color: var(--ag-info); }
.ag-change-text { color: var(--ag-muted); }

/* At 768px and below the two panels stack and the arrow turns downward:
   side-by-side columns of 34ch do not fit, and a horizontally scrolling
   address comparison would defeat the component (§65). */
@media (max-width: 768px) {
  .ag-compare { grid-template-columns: 1fr; }
  .ag-compare-arrow { justify-content: center; transform: rotate(90deg); }
}

/* ---------------------------------------------------------------------------
   Facts row — order value, fulfillment, timing (§24)
   ------------------------------------------------------------------------ */

.ag-facts { display: grid; gap: var(--ag-4);
            grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.ag-fact-label { font-size: var(--ag-t-xs); color: var(--ag-faint);
                 text-transform: uppercase; letter-spacing: .04em;
                 font-weight: var(--ag-w-strong); margin: 0 0 var(--ag-1); }
.ag-fact-value { font-size: var(--ag-t-lg); font-weight: var(--ag-w-med);
                 font-variant-numeric: tabular-nums; margin: 0; }

/* ---------------------------------------------------------------------------
   Timeline (§95)
   ------------------------------------------------------------------------ */

.ag-timeline { list-style: none; margin: 0; padding: 0; }
.ag-tl { display: grid; grid-template-columns: auto 16px 1fr; gap: var(--ag-3);
         align-items: start; }
.ag-tl-time { font-size: var(--ag-t-sm); color: var(--ag-faint);
              font-variant-numeric: tabular-nums; white-space: nowrap; padding-top: 1px; }
.ag-tl-rail { position: relative; display: flex; justify-content: center; }
.ag-tl-dot { width: 8px; height: 8px; border-radius: 50%; margin-top: 6px;
             background: var(--ag-line-firm); flex: none; z-index: 1; }
.ag-tl-dot-active { background: var(--ag-info); }
/* The connecting line is drawn by the rail, not by a border on the row, so the
   last entry has no dangling tail below it. */
.ag-tl:not(:last-child) .ag-tl-rail::after {
  content: ''; position: absolute; top: 14px; bottom: -14px; width: 1px;
  background: var(--ag-line); }
.ag-tl-body { padding-bottom: var(--ag-4); min-width: 0; }
.ag-tl:last-child .ag-tl-body { padding-bottom: 0; }
.ag-tl-title { margin: 0; font-weight: var(--ag-w-body); }
.ag-tl-meta { margin: var(--ag-1) 0 0; font-size: var(--ag-t-sm); color: var(--ag-faint); }

@media (max-width: 480px) {
  /* The time column costs a third of a 390px screen. Below that width it moves
     under the entry instead of beside it. */
  .ag-tl { grid-template-columns: 16px 1fr; }
  .ag-tl-time { grid-column: 2; order: 2; padding: 0; margin-top: var(--ag-1); }
  .ag-tl-body { order: 1; }
}

/* ---------------------------------------------------------------------------
   Loading (§62) — reserved space, never a flash of empty content
   ------------------------------------------------------------------------ */

.ag-skel { background: var(--ag-inset); border-radius: var(--ag-r-sm);
           height: 1em; animation: ag-pulse 1.4s ease-in-out infinite; }
.ag-skel-title { height: 1.5em; width: 42%; }
.ag-skel-line  { width: 100%; }
.ag-skel-line + .ag-skel-line { margin-top: var(--ag-2); }
.ag-skel-short { width: 62%; }

@keyframes ag-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .55; } }

@media (prefers-reduced-motion: reduce) {
  .ag-skel { animation: none; }
}

/* ---------------------------------------------------------------------------
   Utilities
   ------------------------------------------------------------------------ */

.ag-muted  { color: var(--ag-muted); }
.ag-faint  { color: var(--ag-faint); }
.ag-nowrap { white-space: nowrap; }
.ag-num    { font-variant-numeric: tabular-nums; }

/* Visible focus everywhere, on our own controls as much as on Polaris's. */
[tabindex]:focus-visible, button:focus-visible, a:focus-visible {
  outline: 2px solid var(--ag-info); outline-offset: 2px; border-radius: var(--ag-r-sm);
}

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

/* ---------------------------------------------------------------------------
   Dashboard: the action strip and KPIs (§13)
   ------------------------------------------------------------------------ */

/* The one thing a merchant should see first: how much needs them, and a way
   in. Deliberately not a KPI tile — a number with no action beside it is a
   fact, and §13 wants a decision. */
.ag-strip { display: flex; gap: var(--ag-4); align-items: center; justify-content: space-between;
            flex-wrap: wrap; padding: var(--ag-5); border-radius: var(--ag-r);
            border: 1px solid color-mix(in srgb, var(--ag-warn-hue) 40%, transparent);
            background: color-mix(in srgb, var(--ag-warn-hue) 9%, transparent); }
.ag-strip-good { border-color: color-mix(in srgb, var(--ag-good-hue) 35%, transparent);
                 background: color-mix(in srgb, var(--ag-good-hue) 8%, transparent); }
.ag-strip-headline { font-size: var(--ag-t-xl); font-weight: var(--ag-w-title);
                     letter-spacing: -.01em; margin: 0; }
.ag-strip-meta { margin: var(--ag-2) 0 0; color: var(--ag-muted);
                 display: flex; gap: var(--ag-2) var(--ag-4); flex-wrap: wrap; }

.ag-kpis { display: grid; gap: var(--ag-3);
           grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); }
.ag-kpi { padding: var(--ag-4); border-radius: var(--ag-r);
          border: 1px solid var(--ag-line); background: var(--ag-inset); }
.ag-kpi-label { font-size: var(--ag-t-xs); color: var(--ag-faint); margin: 0 0 var(--ag-1);
                text-transform: uppercase; letter-spacing: .04em; font-weight: var(--ag-w-strong); }
.ag-kpi-value { font-size: var(--ag-t-2xl); font-weight: var(--ag-w-title);
                font-variant-numeric: tabular-nums; line-height: 1.1; margin: 0;
                letter-spacing: -.02em; }
.ag-kpi-sub { font-size: var(--ag-t-sm); color: var(--ag-muted); margin: var(--ag-1) 0 0; }

/* ---------------------------------------------------------------------------
   Breakdown bars (§15) and the health bar (§16)

   A restrained chart, per §16: no giant circular gauges. A row of labelled
   bars is read faster than any of them and needs no legend.
   ------------------------------------------------------------------------ */

.ag-bars { display: grid; gap: var(--ag-3); }
.ag-bar-row { display: grid; grid-template-columns: minmax(110px, 1fr) 2fr auto;
              gap: var(--ag-3); align-items: center; }
.ag-bar-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
                font-size: var(--ag-t-sm); }
.ag-bar-track { height: 8px; border-radius: 999px; background: var(--ag-inset); overflow: hidden; }
/* display:block is load-bearing. The track is blockified by being a grid item;
   this span is not, and an inline element ignores width and height — so the
   bar rendered at zero width while looking correctly configured. */
.ag-bar-fill { display: block; height: 100%; border-radius: 999px; min-width: 2px;
               background: color-mix(in srgb, var(--ag-info-hue) 70%, transparent); }
.ag-bar-count { font-size: var(--ag-t-sm); font-variant-numeric: tabular-nums;
                color: var(--ag-muted); min-width: 3ch; text-align: right; }

/* Health is a single stacked bar, not three. The proportions are the point. */
.ag-health { display: flex; height: 10px; border-radius: 999px; overflow: hidden;
             background: var(--ag-inset); }
.ag-health span { display: block; height: 100%; }
.ag-health-good { background: color-mix(in srgb, var(--ag-good-hue) 75%, transparent); }
.ag-health-warn { background: color-mix(in srgb, var(--ag-warn-hue) 80%, transparent); }
.ag-health-bad  { background: color-mix(in srgb, var(--ag-bad-hue) 75%, transparent); }
.ag-health-key  { display: flex; gap: var(--ag-4); flex-wrap: wrap; margin: var(--ag-3) 0 0;
                  font-size: var(--ag-t-sm); color: var(--ag-muted); }
.ag-health-key i { display: inline-block; width: 9px; height: 9px; border-radius: 2px;
                   margin-right: var(--ag-2); }

/* ---------------------------------------------------------------------------
   Resource list (§18, §19)

   NOT a <table>. Each row is a link to one order, which is a list of resources
   rather than tabular data — the same model Polaris's own resource list uses.
   That is what lets the identical markup become cards at 390px without
   stripping table semantics away from a screen reader (§99).
   ------------------------------------------------------------------------ */

.ag-list { display: flex; flex-direction: column; }
.ag-list-head { display: grid; gap: var(--ag-4); padding: 0 var(--ag-4) var(--ag-2);
                font-size: var(--ag-t-xs); text-transform: uppercase; letter-spacing: .04em;
                font-weight: var(--ag-w-strong); color: var(--ag-faint);
                border-bottom: 1px solid var(--ag-line); }
.ag-row-link { display: grid; gap: var(--ag-4); padding: var(--ag-4);
               align-items: center; text-decoration: none; color: inherit;
               border-bottom: 1px solid var(--ag-line); cursor: pointer;
               background: none; border-left: 0; border-right: 0; border-top: 0;
               font: inherit; text-align: left; width: 100%; }
.ag-row-link:hover { background: var(--ag-hover); }
.ag-row-link:focus-visible { outline: 2px solid var(--ag-info); outline-offset: -2px; }

/* Order, customer, address, issue, risk, value — and fulfilment only when
   there is room for it.
   
   Seven columns did not fit an 800px admin: they summed to 762px inside a
   728px row and the last one was clipped away. Fulfilment is the column to
   drop, because §11 makes it context rather than the decision, and the risk
   and the issue are what the merchant is here to read. */
.ag-list-head, .ag-row-link {
  grid-template-columns:
    8ch minmax(80px, 1fr) minmax(120px, 1.5fr) minmax(110px, 1.3fr) minmax(96px, auto) 9ch;
  gap: var(--ag-3);
}

@media (min-width: 1100px) {
  .ag-list-head, .ag-row-link {
    grid-template-columns:
      9ch minmax(90px, 1fr) minmax(140px, 1.6fr) minmax(120px, 1.4fr) minmax(96px, auto) 9ch 10ch;
    gap: var(--ag-4);
  }
}

@media (max-width: 1099px) {
  .ag-cell-fulfil { display: none; }
}

.ag-cell-order { font-weight: var(--ag-w-med); font-variant-numeric: tabular-nums; }
.ag-cell-value { font-variant-numeric: tabular-nums; text-align: right; }
.ag-cell-trunc { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ag-cell-sub   { font-size: var(--ag-t-sm); color: var(--ag-faint); }

/* §19: at 768 and below the row becomes a card. Same DOM, no table to unpick. */
@media (max-width: 768px) {
  .ag-list-head { display: none; }
  .ag-row-link {
    grid-template-columns: 1fr auto;
    grid-template-areas:
      'order value'
      'customer customer'
      'address address'
      'issue issue'
      'status status';
    gap: var(--ag-2);
    border: 1px solid var(--ag-line);
    border-radius: var(--ag-r);
    margin-bottom: var(--ag-3);
  }
  .ag-cell-order    { grid-area: order; }
  .ag-cell-customer { grid-area: customer; }
  .ag-cell-address  { grid-area: address; white-space: normal; }
  .ag-cell-issue    { grid-area: issue; white-space: normal; }
  .ag-cell-value    { grid-area: value; }
  .ag-cell-status   { grid-area: status; margin-top: var(--ag-1); }
  .ag-cell-fulfil   { display: none; }
}

.ag-cell-status { display: flex; gap: var(--ag-2); align-items: center; flex-wrap: wrap; }

/* ---------------------------------------------------------------------------
   Filters (§17)
   ------------------------------------------------------------------------ */

.ag-filters { display: flex; gap: var(--ag-2); flex-wrap: wrap; align-items: center;
              margin: 0 0 var(--ag-4); }
.ag-tab { font: inherit; font-size: var(--ag-t-sm); padding: 5px 12px; border-radius: 999px;
          border: 1px solid var(--ag-line-firm); background: none; color: var(--ag-muted);
          cursor: pointer; white-space: nowrap; }
.ag-tab:hover { background: var(--ag-hover); color: inherit; }
/* Filled and bordered rather than inverted.
   
   The first version set `color: Canvas` and a background of
   `color-mix(in srgb, currentColor 88%, transparent)` on the same rule — and
   currentColor in any property other than `color` resolves to that element's
   OWN used colour, which the rule had just set to white. The background mixed
   white with transparent and the selected tab rendered as an empty pill with
   invisible text. Nothing here inverts, so nothing can trip over that. */
.ag-tab[aria-pressed="true"] { background: color-mix(in srgb, currentColor 12%, transparent);
                               border-color: currentColor; color: inherit;
                               font-weight: var(--ag-w-med); }
.ag-tab-count { opacity: .7; margin-left: var(--ag-1); font-variant-numeric: tabular-nums; }

/* The tab strip scrolls rather than wrapping to three lines on a phone. */
@media (max-width: 560px) {
  .ag-filters { flex-wrap: nowrap; overflow-x: auto; padding-bottom: var(--ag-2);
                scrollbar-width: none; }
  .ag-filters::-webkit-scrollbar { display: none; }
}

.ag-pager { display: flex; gap: var(--ag-3); align-items: center; justify-content: space-between;
            margin-top: var(--ag-4); font-size: var(--ag-t-sm); color: var(--ag-muted);
            flex-wrap: wrap; }

/* ---------------------------------------------------------------------------
   Scan progress (§5)
   ------------------------------------------------------------------------ */

.ag-progress { height: 6px; border-radius: 999px; background: var(--ag-inset); overflow: hidden;
               margin: var(--ag-3) 0 0; }
.ag-progress-fill { height: 100%; border-radius: 999px; transition: width .4s ease;
                    background: color-mix(in srgb, var(--ag-info-hue) 75%, transparent); }
@media (prefers-reduced-motion: reduce) { .ag-progress-fill { transition: none; } }

/* The §74 stale marker in a list row. Sized to sit beside a badge without
   pushing the status column onto a second line. */
.ag-stale { display: inline-flex; align-items: center; justify-content: center;
            width: 22px; height: 22px; border-radius: 50%; flex: none;
            color: var(--ag-muted); border: 1px solid var(--ag-line-firm); }
