/* =============================================================================
   travelmean-autofill.css — A726 (`Q-A712-6`)

   ONE RULE, EVERY SURFACE. The owner's ruling was "Tek bir kural, iki yuzeyde
   birden", and the topology forced this file into existence rather than into an
   existing stylesheet: measured on 2026-08-22 at commit 40727fa2, TWENTY Razor
   files own their own `<head>` and THERE IS NO FIRST-PARTY STYLESHEET THAT ALL
   FOUR SURFACES LOAD. `AutofillMaskIsOneDeclarationTests` derives that population
   from `src/` and requires every head owner to link this file, so a new
   standalone page cannot quietly ship an unmasked field.

   ---------------------------------------------------------------------------
   WHAT THIS FIXES, AND WHY A SHORTER SELECTOR WOULD HAVE BEEN A NO-OP
   ---------------------------------------------------------------------------
   Chrome paints a saved credential with its OWN ground. `background-color` does
   not reach it at any specificity; the only lever is an inset box-shadow large
   enough to cover the field, plus `-webkit-text-fill-color` for the text the
   same engine repaints.

   The portal already had that mask and IT DIED THE MOMENT A READER FOCUSED THE
   FIELD. Measured live (image travelmeanwebservice:local-20260822015348,
   /agency/login, 1440 / dpr 1.0) — the control group is what gave the verdict:

     agencyPassword  autofilled, NOT focused -> box-shadow rgb(255,255,255) ... inset   MASK ALIVE
     agencyEmail     autofilled, FOCUSED     -> box-shadow none                          MASK DEAD

   The killer is a single eight-armed block in the vendor theme
   (`assets/css/app.css`, served as `app.min.css`) — search it by its text
   rather than by a line number, which shifts:

     .custom-select.is-invalid:focus, .form-control.is-invalid:focus,
     .custom-select:invalid:focus,    .form-control:invalid:focus,
     .custom-select.is-valid:focus,   .form-control.is-valid:focus,
     .custom-select:valid:focus,      .form-control:valid:focus {
         box-shadow: none !important;
     }

   FOUR of those eight arms are `.form-control`, and every focused control is
   either `:valid` or `:invalid`, so the block is effectively
   `.form-control:focus { box-shadow: none !important }`. A CSSOM scan of the
   live portal found exactly ONE rule in the whole document matching
   "box-shadow:none!important on a form control" — this one.

   🔴 AN AUTHOR `!important` BEATS EVERY NON-IMPORTANT AUTHOR DECLARATION
   REGARDLESS OF SPECIFICITY, so writing a longer selector does not save you.
   Proven here rather than assumed, with a deterministic cascade experiment
   against a stand-in of the same specificity (`:-webkit-autofill` cannot be
   forced from script, so the contest was reproduced with pseudo-classes that
   can):

     higher specificity, NOT important -> computed `none`                LOSES
     higher specificity, AND important -> computed `... 0 0 0 7px ...`   WINS

   So the counter-rule below must be `!important` AND out-specify (0,3,0).
   `:is(input,textarea,select)` = (0,0,1), `:-webkit-autofill` = (0,1,0),
   `:focus` = (0,1,0), `:is(:valid,:invalid,:read-only)` = (0,1,0)
   -> (0,3,1), which is one element-unit above the theme.

   🔴 AND THE GROUP MUST HOLD WHILE THE FIELD IS INVALID, because four of the
   theme's eight arms attack exactly that state — i.e. the moment the reader has
   made a mistake. `:valid` alone would leave the mask dead there. The third
   member, `:read-only`, is not decoration either: `readonly` and `disabled`
   controls are BARRED from constraint validation and match NEITHER `:valid` nor
   `:invalid`, so without it the group could fail to match and the whole
   declaration would vanish. Measured exhaustive over eight shapes
   (text / email / password / text[readonly] / email[required] / number /
   textarea / select) — all true.

   ---------------------------------------------------------------------------
   COLOUR: TWO INDIRECTION TOKENS, ONE BINDING PER PALETTE
   ---------------------------------------------------------------------------
   There are four palette dialects for "field ground / field ink" and this file
   must not know any of them. Each palette binds the two tokens ONCE, next to
   its own declarations, with `var()` — so the value is resolved late and every
   surface follows its OWN light/dark switch (and its theme presets) with no
   second declaration here. Measured, ground/ink against a REAL non-autofilled
   field on each surface rather than read off the token names:

     storefront-base.css        --tm-surface / --tm-ink        #ffffff/#110f0f 19.11:1   dark #1b1b1f/#f5f5f7 15.77:1
     travelmean-tokens.css      --surface    / --ink           #ffffff/#22333b 13.09:1   dark #36404a/#b0bbc7  5.42:1
     travelmean-standalone.css  --sa-surface / --sa-field-ink  #ffffff/#4B4B5A  8.56:1   dark #1b1b1f/#f5f5f7 15.77:1
     agency-portal.css          --ag-card-bg / --ag-page-ink   #ffffff/#110f0f 19.11:1   dark #1b1b1f/#f5f5f7 15.77:1

   Every pair clears AA in both schemes; the weakest is 5.42:1.

   🔴 GROUND IS A SURFACE TOKEN AND INK IS AN INK TOKEN, NEVER THE OTHER WAY
   ROUND (A574/A577). `--tm-ink` and `--tm-surface` INVERT between schemes, so
   borrowing one as the other yields white-on-white in dark. And the ink half is
   not optional: the engine repaints the TEXT too, so fixing the ground while
   leaving `-webkit-text-fill-color` alone produces an unreadable field.

   🔴 THE FALLBACKS ARE LOAD-BEARING, NOT DECORATION. Two head owners carry only
   the vendor theme and no palette at all (`VisaUpload/Index`,
   `Error/ApplicantStatus`). Measured: `var(--undeclared)` with NO fallback makes
   the WHOLE shorthand invalid at computed-value time — `box-shadow` came back
   `none`, i.e. the mask would silently disappear on exactly those pages. The
   system colours were measured to resolve AND to follow `color-scheme`:
   `Field`/`FieldText` = #ffffff/#000000 (21.00:1) and rgb(59,59,59)/#ffffff
   (11.20:1) under `color-scheme: dark`.

   ---------------------------------------------------------------------------
   🔴 THE NAME OF THIS FILE IS NARROWER THAN ITS JOB, AND THAT IS DELIBERATE
   ---------------------------------------------------------------------------
   A747 added a SECOND rule here — the focus ring — so "autofill" no longer
   describes everything in the file. A file name is an assertion (A564) and the
   honest answer would normally be a rename. It was measured and rejected:
   34 references, eight of them DATED QA records that cite this path as the
   evidence for a live measurement. Renaming would strand those citations, which
   is the same damage as a shifted line number (A619) — a reference that cannot be
   followed makes the thing it points at unverifiable even when it is right.

   So the scope is stated instead: THIS IS THE SHARED FIELD-STATE LAYER. It owns
   the two things a form field's painted state needs that no single surface can
   own alone, because there is no other first-party stylesheet all four surfaces
   load. Both rules read palette-bound tokens and neither knows a colour.

   ---------------------------------------------------------------------------
   `--tm-focus-ring` — A DECLARED SEAM, NOW BOUND BY EVERY PALETTE (A732, A747)
   ---------------------------------------------------------------------------
   `box-shadow` is ONE property, so an important mask replaces any focus ring
   rather than sitting beside it. The seam exists so that a ring restoration
   cannot land half-applied: it is written as a `var()` FALLBACK, so a palette
   that says nothing costs nothing, and a palette that declares `--tm-focus-ring`
   gets its ring composed onto the autofilled focused field instead of losing it.

   🔴 IT IS NO LONGER UNBOUND, AND THAT IS THE POINT. This paragraph used to say
   "bound NOWHERE" and would have quietly become a lie. A732 restored the agency
   portal's designed ring and bound the seam there — once on `.ag-shell` for the
   brand ring, and again on the `:user-invalid` / `.is-invalid` selectors so a
   REFUSED autofilled field answers in red rather than brand. Measured on
   /agency/login with a genuinely autofilled, focused field: the computed value
   came back as the ring AND the inset ground, composed, in both schemes.

   The prediction underneath the seam held exactly as written: A732's restoration
   sits at (0,4,0) with `!important`, which DOES outrank this rule at (0,3,1), so
   without a seam autofilled fields alone would have stayed ringless — silently.
   What actually prevents that is not the seam alone but the restoration excluding
   `:-webkit-autofill` from its own selector; the seam is what then puts the ring
   back. Both halves are required, and they live in agency-portal.css.

   🔴 A747 — THE SEAM IS THE TOKEN NOW, NOT A SIDE DOOR, AND IT WAS RENAMED FOR IT.
   It was called `--tm-autofill-ring` while exactly one rule read it. The owner's
   round-7 answer 4 (2026-08-22) put a ring on the other three surfaces, so it has
   two readers: the arm above composes it with the mask, and the rule at the bottom
   of this file paints it on a field the browser has NOT filled. A second token
   holding a byte-identical value would be the copy shape A698 records — a parity
   pin can only ever call two copies "consistent", never "right". So: ONE token,
   ONE binding per palette, TWO rules. This paragraph's old warning that "the other
   three surfaces still bind nothing, and that is still correct" is retired rather
   than edited: it was correct until the decision was taken, and it is now false.

   ⚠️ THE FALLBACK IS STILL LOAD-BEARING — two head owners carry no palette at all
   (`VisaUpload/Index`, `Error/ApplicantStatus`), and an unresolvable var() with no
   fallback invalidates the whole shorthand. Do not "simplify" it away.

   ⚠️ AND IT IS THE ONLY WAY A CONTROL COMES OUT, WHICH IS WHY THE RULE BELOW
   SELECTS BY CLASS. An earlier draft of this wave selected `input, textarea,
   select` and needed a re-binding to `0 0 0 0 transparent` on `.sf-field` to stop
   the shop window drawing two rings round one control. Narrowing the selector to
   the class family the vendor block attacks removed the need for any opt-out at
   all — and an opt-out is a thing a later reader copies without the reasoning
   that made it correct. Nothing in the repository re-binds this token to nothing
   today; `FocusRingContrastTests` refuses a transparent binding for that reason.
   ============================================================================= */

:is(input, textarea, select):-webkit-autofill,
:is(input, textarea, select):-webkit-autofill:hover {
    -webkit-text-fill-color: var(--tm-autofill-ink, FieldText) !important;
    -webkit-box-shadow: 0 0 0 1000px var(--tm-autofill-ground, Field) inset !important;
    box-shadow: 0 0 0 1000px var(--tm-autofill-ground, Field) inset !important;
    caret-color: var(--tm-autofill-ink, FieldText);
}

/* The focused arm. (0,3,1) + `!important` — see the specificity note above; at
   (0,3,0) or without `!important` this is a no-op in exactly the state the
   reader is looking at. */
:is(input, textarea, select):-webkit-autofill:focus:is(:valid, :invalid, :read-only) {
    -webkit-text-fill-color: var(--tm-autofill-ink, FieldText) !important;
    -webkit-box-shadow: var(--tm-focus-ring, 0 0 0 0 transparent),
                        0 0 0 1000px var(--tm-autofill-ground, Field) inset !important;
    box-shadow: var(--tm-focus-ring, 0 0 0 0 transparent),
                0 0 0 1000px var(--tm-autofill-ground, Field) inset !important;
}

/* ============================================================================
   THE FOCUS RING — A747 (`Q-A726-1` / `Q-A732-1`)

   The SAME token, on the fields the arm above cannot reach: the ones the browser
   has NOT filled in, which is nearly all of them. Written here rather than four
   times because there is exactly one stylesheet every surface loads (that is why
   this file exists at all) and a rule copied into four palettes is the shape A700
   records — a hand-maintained owner list that goes incomplete in silence.

   🔴 WHY IT HAS TO BE `!important`, AND WHY THAT IS NOT AN ESCALATION. The vendor
   theme's eight-arm block quoted at the top of this file does not only kill the
   autofill mask; it kills EVERY shadow on EVERY focused `.form-control`, which is
   the class the admin panel and the admin sign-in page use for every field they
   have. Measured before this rule existed: the admin sign-in sheet
   (travelmean-standalone.css) contained ZERO focus declarations of any kind, and
   the panel's own `--focus-ring` token was read only by four `tm-` components —
   no input, anywhere, drew a designed ring. The specificity is checked rather
   than asserted (FocusRingContrastTests computes it):
     `:is(.form-control,.form-select)`(0,1,0) + `:focus`(0,1,0)
     + `:is(:valid,:invalid,:read-only)`(0,1,0) + `:not(:is(:-webkit-autofill))`(0,1,0)
     = (0,4,0), one class-unit above the theme's (0,3,0).

   🔴 IT SELECTS BY CLASS, NOT BY ELEMENT, AND THE FIRST DRAFT DID THE OPPOSITE.
   `:is(input, textarea, select)` reads as the more general, more generous choice
   and it is the wrong one, because this rule is `!important`: it then outranks
   every non-important decision a surface has already made about a control that is
   not a text field. Two were measured in the tree before the scope was narrowed,
   and both were deliberate:
     agency-portal.css  `.ag-shell .form-check-input:focus { box-shadow: none }`
       — (0,3,0), non-important. A checkbox there is 16px and answers focus with
       the portal's outline ring; a 3px opaque box-shadow would put a second ring
       round it, on four views.
     storefront-base.css `.sf-field input` / `select` carry `border: 0` and a
       transparent background because the ring is drawn on the BOX around them
       (`.sf-field:has(input:focus-visible)`), so an inner ring would draw two
       boxes for one control — on the home page's search panel.
   Both would have needed an opt-out, and an opt-out is a thing somebody later
   copies without the reasoning. `.form-control` / `.form-select` is also exactly
   the family the vendor block attacks, so the rule's reach is the defect's reach
   rather than a superset of it.
   ⚠️ THE COST IS STATED: a bare `<input>` with no class gets nothing from here.
   Measured — the storefront renders ZERO `.form-control` elements (its fields are
   `.sf-*`), so this rule is inert there today and the shop window's visible ring
   is its `:focus-visible` outline, which predates this wave and is measured by
   FocusRingContrastTests alongside these.

   🔴 `:not(:is(:-webkit-autofill))` IS WHAT KEEPS THE MASK ALIVE, and it is the
   same load-bearing shape A732 wrote for the portal. `box-shadow` is ONE property:
   this rule and the arm above are at the SAME specificity, so if both could match
   one element the later one would simply replace the earlier, and an autofilled
   focused field would lose its ground. They are made mutually exclusive by
   construction instead of by source order. `:is()` inside `:not()` is likewise not
   style — `:not()` is unforgiving, so an engine that does not know
   `:-webkit-autofill` would throw the whole selector away and every ring with it.

   ⚠️ ONLY THE UNPREFIXED PROPERTY IS WRITTEN. A732 measured that Blink treats the
   `-webkit-` name as an alias of the same property and read the same computed
   value back from one declaration; the vendor writes both, it does not need to be
   answered twice. The arm above keeps both because a var() fallback chain there
   already had two spellings to keep in step.

   ⚠️ AND THE FALLBACK IS LOAD-BEARING for the same reason it is above: two head
   owners carry no palette at all (`VisaUpload/Index`, `Error/ApplicantStatus`),
   and an unresolvable var() with no fallback invalidates the WHOLE shorthand at
   computed-value time. `0 0 0 0 transparent` means "this palette has not asked
   for a ring", and a page with no palette is exactly that case.
   ============================================================================ */
:is(.form-control, .form-select):focus:is(:valid, :invalid, :read-only):not(:is(:-webkit-autofill)) {
    box-shadow: var(--tm-focus-ring, 0 0 0 0 transparent) !important;
}
