/* ============================================================
   Panel surfaces — the layout the #818 mockups settled, on the
   pages of both panels.
   ------------------------------------------------------------
   The mockups (`docs/mockups/` on the `worktree-argos-login-mockup`
   branch) were built to decide a layout BEFORE any of this was
   written. What lands here is the part of them that is CSS on top
   of Filament's own markup: the backdrop, the chrome surfaces, the
   overline type role, the tabs, the table and the fields.

   Where a mockup value and a design-system rule disagree, the design
   system wins, and every such place says so where it happens. The
   mockups were drawn with literal hex values; this file references
   `--tew-*` tokens, so a change upstream reaches the panels.

   Everything here is unlayered on purpose, which is what lets a plain
   `.fi-tabs-item` beat Filament's `.fi-tabs-item.fi-active:hover`: its
   component styles live in a cascade layer, and an unlayered rule
   wins over a layered one whatever the specificity.
   ============================================================ */

/* ------------------------------------------------------------
   1. THE KNOB — how much of the backdrop the chrome lets through
   ------------------------------------------------------------
   One number for the three surfaces that frame every page: the
   topbar, the sidebar and the pinned footer bar (#547, #1129). 0 is
   solid, 1 is invisible, and the blur follows it — at 0 there is none,
   which is the point: `backdrop-filter` over a scrolling page is
   recomputed on every frame.

   It is 0 because the mockups settled on 0. Until #818 the footer bar
   alone sat at 0.10 with a 4px blur, the one translucent surface in a
   frame of solid ones; it now matches the other two, which is also
   what makes it the knob's third reader rather than an exception.
   Move it from the inspector (`:root { --ssmt-chrome-veil: .15 }`)
   and all three move together.
   ------------------------------------------------------------ */
:root {
    --ssmt-chrome-veil: 0;
}

.fi-topbar,
.fi-sidebar,
.ssmt-footer-bar {
    background-color: color-mix(
        in srgb,
        var(--tew-color-surface) calc((1 - var(--ssmt-chrome-veil)) * 100%),
        transparent
    );
    backdrop-filter: blur(calc(var(--ssmt-chrome-veil) * 40px));
}

/* Filament leaves the docked sidebar transparent, so until now it was the
   page background with links on it. Over the backdrop it has to be a surface
   of its own, and a surface next to another one needs an edge. */
@media (min-width: 1024px) {
    .fi-sidebar {
        border-inline-end: 1px solid var(--tew-color-border);
    }
}

/* ------------------------------------------------------------
   2. THE BACKDROP — `filament/backdrop.blade.php`
   ------------------------------------------------------------
   Behind the layout, never on top of it: `z-index: -1` in the root
   stacking context paints it over the canvas and under everything in
   flow, with no wrapper that would have to be positioned — a
   positioned wrapper around the layout would be a stacking context,
   and Filament's modals inside it would sit under the footer bar.

   The page background stays Filament's and is painted underneath (the
   body's background propagates to the canvas): the aurora TINTS it, so
   a browser that cannot draw the gradient still shows the page it
   showed before.

   Alphas and positions are the mockups', translated from literal rgba
   into the brand tokens. Dark carries roughly twice the light alphas
   because the same tint on a dark ground reads as half as much.

   ⚠️ A TINTED PAGE SPENDS SOMEBODY ELSE'S CONTRAST BUDGET, so it was
   measured rather than assumed. The design system checks its
   subtle-text role against a FLAT background; ours is no longer flat,
   and on the sign-in page — where labels sit straight on the aurora
   with no surface between — the aurora costs about a full point of
   ratio and pushed three of them under AA (the numbers, and the step
   down that fixed them, are in `login-split.css` §0).

   On a PANEL page it does not, and the reason is §1: the topbar, the
   sidebar and the footer bar are opaque at `--ssmt-chrome-veil: 0`,
   and tables, sections and widgets all paint their own surface. The
   text that touches the backdrop is the breadcrumb, sampled from the
   rendered pixels at 4.60:1 light and 5.77:1 dark — thin, and above
   the floor — and the idle labels of an uncontained tab strip, which
   did NOT clear it (4.49:1) and were stepped down in §5. The two labels
   that look like they would be at risk, the sidebar group and the
   pagination overview, both measured 5.53:1 exactly: they are on
   white, not on the aurora.

   🚨 So: the day `--ssmt-chrome-veil` is moved off 0, or a page puts
   small text directly on the page background, this measurement stops
   holding — and the axe gate will NOT tell you. axe resolves a
   background by walking ancestors' computed `background-color`; a
   fixed gradient layer at `z-index: -1` is not one, so it measures
   `.fi-body`'s flat grey and passes.
   ------------------------------------------------------------ */
.ssmt-backdrop {
    position: fixed;
    inset: 0;
    z-index: -1;
    overflow: hidden;
    pointer-events: none;

    --ssmt-aurora-1: color-mix(in srgb, var(--tew-blue-500) 38%, transparent);
    --ssmt-aurora-2: color-mix(in srgb, var(--tew-blue-400) 32%, transparent);
    --ssmt-aurora-3: color-mix(in srgb, var(--tew-green-500) 34%, transparent);
    --ssmt-grid-line: color-mix(in srgb, var(--tew-blue-900) 7%, transparent);
    --ssmt-vignette: color-mix(in srgb, var(--tew-blue-900) 7%, transparent);
}

.dark .ssmt-backdrop {
    --ssmt-aurora-1: color-mix(in srgb, var(--tew-blue-500) 78%, transparent);
    --ssmt-aurora-2: color-mix(in srgb, var(--tew-blue-400) 60%, transparent);
    --ssmt-aurora-3: color-mix(in srgb, var(--tew-green-500) 46%, transparent);
    --ssmt-grid-line: color-mix(in srgb, var(--tew-blue-200) 7.5%, transparent);
    --ssmt-vignette: color-mix(in srgb, var(--tew-gray-900) 30%, transparent);
}

.ssmt-backdrop__aurora,
.ssmt-backdrop__grid,
.ssmt-backdrop__vignette {
    position: absolute;
    inset: 0;
}

/* 🚨 THE BLUR HERE WAS ONCE BLAMED FOR A FAULT IT DID NOT CAUSE, and the
   retraction is worth more than the finding. This layer carried
   `blur(70px) saturate(135%)`, the mockup's, and it was removed on a
   measurement: `ValueNoteTooltipTest` passed 2 runs in 6 with the blur and
   6 in 6 with the backdrop hidden, failing on 5-second timeouts on
   `visit()`. The correlation was real and the conclusion was wrong.

   What was actually filling those 5 seconds: the browser container had
   leaked 69 Playwright servers from earlier runs, about 80 MB each, and at
   4.8 GiB of a 7.7 GiB Docker VM it was being OOM-killed mid-test
   (`docker inspect -f '{{.State.OOMKilled}}'` said `true`). A restarted
   container passes the same test 8 runs in 8 WITH the blur and 8 in 8
   without, and the frame rate is 23 either way: the layer is painted once,
   so a static filter on it costs nothing per frame.

   The lesson, since the blur is back and the trap is not: a test that fails
   while a machine is starving measures the machine. Before believing any
   A/B on this suite, check `docker stats` and restart the container — and
   interleave the two sides, so a drift in load cannot land on one of them.

   Oversized on purpose: the lobes' positions and sizes are percentages of
   THIS box and were tuned on it. */
.ssmt-backdrop__aurora {
    inset: -25%;
    filter: blur(70px) saturate(135%);
    background:
        radial-gradient(58% 52% at 30% -4%, var(--ssmt-aurora-1), transparent 64%),
        radial-gradient(52% 46% at 96% 16%, var(--ssmt-aurora-2), transparent 62%),
        radial-gradient(74% 54% at 60% 102%, var(--ssmt-aurora-3), transparent 64%);
}

.ssmt-backdrop__grid {
    background-image:
        linear-gradient(90deg, var(--ssmt-grid-line) 1px, transparent 1px),
        linear-gradient(var(--ssmt-grid-line) 1px, transparent 1px);
    background-size: 56px 56px;
    /* A mask reads the ALPHA of a gradient and nothing else, so `black` here
       means «opaque», not a colour. Written as the keyword, not a hex, on
       purpose: `CssTokensTest` holds every hex to the design system, and a
       mask stop is the one place where there is no colour to hold. */
    mask-image: radial-gradient(90% 80%, black 35%, transparent 95%);
}

.ssmt-backdrop__vignette {
    background: radial-gradient(ellipse at center, transparent 40%, var(--ssmt-vignette) 92%);
}

/* ------------------------------------------------------------
   3. THE OVERLINE — one type role for every label that names a
      column of things rather than being one of them
   ------------------------------------------------------------
   Sidebar group, table column, breadcrumb, stat caption, panel badge:
   the mockups set all five in the same small uppercase mono, and it is
   the design system's `overline` role — so the size and the tracking
   are ITS tokens (0.75rem, 0.12em), not the mockups' 9.5px, which in
   uppercase mono is a texture more than a label. One exception, the
   table header, measured and written down in §6.

   Colour is not set here. Four of the five already take the DS
   subtle-text role from the accessibility block in `theme.css`, and
   the header cell takes it below: this rule is typography only, so it
   cannot undo a contrast fix by being loaded later.
   ------------------------------------------------------------ */
.fi-sidebar-group-label,
.fi-ta-header-cell,
.fi-breadcrumbs-item-label,
.fi-wi-stats-overview-stat-label,
.ssmt-panel-badge {
    font-family: var(--tew-font-mono);
    font-size: var(--tew-text-overline);
    font-weight: 500;
    letter-spacing: var(--tew-tracking-overline);
    text-transform: uppercase;
}

/* ------------------------------------------------------------
   4. SIDEBAR
   ------------------------------------------------------------ */

/* The active item gets the same 2px edge Filament already draws on a
   SELECTED table row: one sign for «this is the one», in both places. */
.fi-sidebar-item.fi-active > .fi-sidebar-item-btn {
    box-shadow: inset 2px 0 0 0 var(--primary-600);
}

.dark .fi-sidebar-item.fi-active > .fi-sidebar-item-btn {
    box-shadow: inset 2px 0 0 0 var(--primary-500);
}

[dir='rtl'] .fi-sidebar-item.fi-active > .fi-sidebar-item-btn {
    box-shadow: inset -2px 0 0 0 var(--primary-600);
}

/* Which panel this is, at the top of the admin sidebar
   (`filament/admin/panel-badge.blade.php`). The client panel has its own
   answer in the same slot: the client block. */
.ssmt-panel-badge {
    display: inline-flex;
    align-self: flex-start;
    align-items: center;
    gap: 0.4rem;
    padding: 0.3rem 0.6rem;
    border: 1px solid var(--tew-color-border);
    border-radius: var(--tew-radius-pill);
    color: var(--tew-color-text-muted);
}

.ssmt-panel-badge__icon {
    width: 0.875rem;
    height: 0.875rem;
    flex: none;
}

/* ------------------------------------------------------------
   5. TABS — an underline, not a pill
   ------------------------------------------------------------
   The list tabs («Tutti · Organico · Sponsorizzato») were a centred pill
   box floating over the page; the mockups put them on the page's own
   left edge, on a hairline, with the active one marked by the brand
   gradient underneath. The dashboards' tabs are bare too, since the GUI
   review of #818: they navigate between groups of charts, they are not a
   card around them. The contained tabs that remain (record pages, the
   profile) get the same mark, so a tab looks like a tab wherever it is.

   The strips lose their bottom padding so the items sit ON the hairline:
   the underline is drawn at the item's bottom edge, and any padding
   below it would leave the mark floating above the line it belongs to.

   ⚠️ The hairline is an inset shadow, not a border, and that is what lets
   the underline cover it. The strip is `overflow-x: auto` (it scrolls when
   the tabs outgrow it), so an underline pushed 1px out of it to sit on a
   border is overflow — and measured, it grew the strip a vertical
   scrollbar. An inset shadow is painted INSIDE the box, where the
   underline already is.
   ------------------------------------------------------------ */
.fi-tabs:not(.fi-contained) {
    margin-inline: 0;
    padding: 0;
    border-radius: 0;
    background-color: transparent;
}

.fi-tabs:not(.fi-vertical) {
    border-bottom-width: 0;
    box-shadow: inset 0 -1px 0 0 var(--tew-color-border);
}

.fi-tabs.fi-contained:not(.fi-vertical) {
    padding-block-end: 0;
}

.fi-tabs-item {
    position: relative;
    border-radius: 0;
    background-color: transparent;
    font-weight: 600;
}

/* Filament marks keyboard focus with the background this file just took
   away, so the focus needs a sign of its own — without one, tabbing
   through the strip shows nothing at all. */
.fi-tabs-item:focus-visible {
    border-radius: var(--tew-radius-sm);
    box-shadow: inset 0 0 0 2px var(--primary-600);
}

.fi-tabs:not(.fi-vertical) .fi-tabs-item.fi-active::after {
    content: '';
    position: absolute;
    inset-inline: 0.55rem;
    bottom: 0;
    height: 0.125rem;
    border-radius: 2px;
    background: var(--tew-gradient-brand);
}

/* 🚨 AN UNCONTAINED STRIP SITS ON THE BACKDROP, and its idle labels pay for
   it. `theme.css` gives every tab label the subtle role, checked by the
   design system at 5.53:1 against flat white. A contained strip is on a
   card, where that holds. An uncontained one — the dashboards since #818,
   the list tabs — is on the aurora, and sampled from the rendered page at
   1440×900 the admin dashboard's «Clientela» measured 4.49:1 at worst and
   «Salute & dati» 4.71:1 in light mode (5.66+ in dark). So the idle labels
   of a bare strip step down to the muted role, re-measured on the same
   pixels at 7.42:1; «which one is open» was never the colour's job — the
   underline below says it. */
.fi-tabs:not(.fi-contained) .fi-tabs-item:not(.fi-active) .fi-tabs-item-label {
    color: var(--tew-color-text-muted);
}

/* The active label goes to the strong text colour and the gradient says
   «selected»; Filament's primary label on top of the gradient would say it
   twice, in two colours. */
.fi-tabs-item.fi-active .fi-tabs-item-label {
    color: var(--tew-color-text);
}

/* The count after a tab label is a figure, not a status: mono, no pill. */
.fi-tabs-item .fi-badge {
    min-width: 0;
    padding-inline: 0;
    background-color: transparent;
    box-shadow: none;
    color: var(--tew-color-text-subtle);
    font-family: var(--tew-font-mono);
    font-variant-numeric: tabular-nums;
    font-weight: 500;
}

/* ------------------------------------------------------------
   6. TABLES
   ------------------------------------------------------------ */

/* Column headers step back to the subtle role: they name the data and
   should not compete with it. Filament paints them at full strength and
   semibold. The overline block above sets the type...

   ⚠️ ...except its size, the one place the overline leaves the DS, and it
   is measured. A header wider than its column widens the column, and
   uppercase mono with tracking is wider than the sentence-case Mulish it
   replaces. On the client content list at 1440px (container 1041px): the
   table was 1170px wide, and at the DS overline it grows to 1275px — the
   «Pubblicato il» column leaves the screen. At 0.6875rem and 0.08em it is
   1200px: +30px instead of +105. The list scrolled sideways before #818 and
   still does; what this keeps is the column that was on screen staying
   there. */
.fi-ta-header-cell {
    color: var(--tew-color-text-subtle);
    font-size: 0.6875rem;
    letter-spacing: 0.08em;
}

/* Figures at the foot of the table read as data: mono, fixed-width digits,
   so «1–10 di 328» does not jiggle as the pages change. The overview is a
   caption, not body text: the subtle role and the caption size. */
.fi-pagination-overview,
.fi-pagination-item-label {
    font-family: var(--tew-font-mono);
    font-variant-numeric: tabular-nums;
}

.fi-pagination-overview {
    font-size: var(--tew-text-caption);
    color: var(--tew-color-text-subtle);
}

/* The row that opens a record has to LOOK like it does (the
   `list-row-affordance` mockup). Filament's hover tint is gray-50, which on
   white is 1.06:1 — below what an eye running down a list notices. gray-100
   doubles the step, and in dark the tint goes from 5% to 9% white. */
.fi-ta-row.fi-clickable:hover {
    background-color: var(--tew-gray-100);
}

.dark .fi-ta-row.fi-clickable:hover {
    background-color: color-mix(in srgb, var(--tew-gray-white) 9%, transparent);
}

/* ...and the row's NAME reads as the link it is: link colour and an
   underline, on hover only — at rest the list does not change by a pixel.

   🚨 Which cell is the name is not guessed, and the first guess was wrong.
   The mockup drew «the first column», and on the admin brand list the first
   text column is the CLIENT: the row opens the brand while the client's name
   lights up. So the name is the column CALLED `name` (or `label`, the
   token list's) — Filament stamps the column's name on its cell as
   `fi-ta-cell-<name>`. `client.name` is a different class, so a parent's
   name never qualifies. A list with no such column — the content lists,
   whose rows have no name — gets the tint and nothing else, which is true.

   And a cell whose link goes somewhere else is never dressed as the row's:
   Filament marks it `fi-ta-col-has-column-url`. */
.fi-ta-row.fi-clickable:hover
    > :is(.fi-ta-cell-name, .fi-ta-cell-label):has(a.fi-ta-col:not(.fi-ta-col-has-column-url))
    .fi-ta-text-item {
    color: var(--tew-color-link);
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 2px;
}

/* ------------------------------------------------------------
   7. FIELDS — never translucent, and outlined at 3:1
   ------------------------------------------------------------
   A field that lets the page through changes contrast with whatever
   happens to be behind it, and the placeholder is the first thing to go.
   Filament fills its dark fields with 5% white, which was harmless while
   every page was a flat grey and is not over the aurora. The fill is now
   the same colour, computed once instead of blended at paint time: on a
   card it looks exactly as it did.

   The outline carries the other half. Where the fill is the card's own
   colour — white on white in light — the outline is the only thing that
   identifies the control, and WCAG 1.4.11 wants 3:1 from it alone.
   Filament's is 10% black, about 1.3:1. The DS gray-500 clears 3:1 on
   white and on the dark field alike. Resting state only: focus, error and
   disabled keep Filament's own rings.

   The placeholder is text: gray-400 on white is 2.32:1, the value
   `theme.css` already names as a failure. It takes the subtle-text role.
   ------------------------------------------------------------ */
.dark .fi-input-wrp:not(.fi-disabled) {
    background-color: color-mix(in srgb, var(--tew-gray-white) 5%, var(--tew-color-surface));
}

.fi-input-wrp:not(.fi-disabled):not(.fi-invalid):not(:focus-within) {
    --tw-ring-color: var(--tew-gray-500);
}

.fi-input::placeholder {
    color: var(--tew-color-text-subtle);
}
