/* Status indicator (e.g., Poisoned) */
.status-indicator {
    --status-rail-edge: max(
        calc(4.7vmin + 6px),
        env(safe-area-inset-right, 0px)
    );
    position: absolute;
    bottom: -12px; /* place below portrait */
    left: 50%;
    transform: translateX(-50%);
    width: max-content;
    max-width: min(
        280px,
        calc(100% + var(--status-rail-edge) + var(--status-rail-edge) - 2px)
    );
    box-sizing: border-box;
    padding: 0;
    color: #fff8df;
    font-size: 12px;
    font-weight: bold;
    line-height: 1.2;
    white-space: normal;
    display: flex;
    flex-flow: row wrap;
    justify-content: center;
    align-items: flex-start;
    gap: 2px;
    text-align: center;
    z-index: 30;
}

/* main.css intentionally restores pointer events on all descendants. Status
   copy is presentation only, so make the complete subtree transparent to
   attacks, card taps, and drags—not just its background container. */
.status-indicator,
.status-indicator * {
    pointer-events: none;
}

/* The accent is the effect's colour, assigned by UI.StoryFeed.getStatusColor so
   one status keeps one colour across the storyboard prose, the card overlay and
   this rail. The WORD carries it — tinting only the edge left every status the
   same cream and taught the player nothing. */
.status-effect-chip {
    --status-effect-accent: #eac761;
    display: block;
    max-width: 100%;
    box-sizing: border-box;
    padding: 2px 7px;
    border-left: 2px solid var(--status-effect-accent);
    border-radius: 5px;
    background: rgba(14, 9, 22, 0.94);
    /* The word takes the READABLE form of the accent (indicators.js measures it
       against this background); the border keeps the palette colour exactly.
       Falls back to the raw accent so a chip rendered before the helper loads
       still carries its colour rather than none. */
    color: var(--status-effect-text, var(--status-effect-accent));
    overflow-wrap: break-word;
    word-break: normal;
    hyphens: auto;
    text-wrap: balance;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.98);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.08),
        0 2px 6px rgba(0, 0, 0, 0.62);
}

/* Adjust offsets per portrait */
#player-status-indicator {
    bottom: calc(100% + var(--summoner-nameplate-gap));
}

#opponent-status-indicator {
    top: calc(100% + var(--summoner-nameplate-reserve) + var(--summoner-nameplate-gap));
    bottom: auto;
}

/* The tablet portrait rail deliberately sits beside the centred board with a
   very small seam. Preserve the established centred attachment while keeping
   the badge inside the portrait's own horizontal lane. */
@media (orientation: landscape) and (min-width: 960px) and (min-height: 561px) and (max-width: 1560px) and (max-aspect-ratio: 17/10) {
    .status-indicator {
        max-width: min(280px, 100%);
    }
}

/* The full-size landscape treatment retains the established external rails. */
@media (orientation: landscape) and (max-height: 560px) {
    #opponent-status-indicator {
        top: calc(100% + var(--summoner-nameplate-reserve) + var(--summoner-nameplate-gap));
        bottom: auto;
    }

    #player-status-indicator {
        bottom: calc(100% + var(--summoner-nameplate-gap));
    }
}

@media (orientation: landscape) and (max-height: 560px) and (max-width: 932px) {
    :root {
        /* The shared 128px utility rail is the largest budget that keeps the
           clipped deck stacks outside the centred board on taller phones. */
        /* THE RAIL IS SQUEEZED FROM BOTH SIDES, so it is a clamped range rather
           than a multiple of anything.

           WIDER keeps the plate SHORT. The 40-glyph unbroken ledger — the
           tallest fixture the status audit renders — wraps to four lines
           anywhere from 112px to 128px and to five at 104px, measured on every
           landscape page box. Five lines do not fit between the crest's top
           edge and its resource discs.

           NARROWER keeps the deck stack off the board. The deck is anchored one
           rail-width plus 8px inboard of the summoner column, so every pixel of
           rail pushes it toward slot five. At 667x275 — the tightest real box,
           and the only one where the off-stage deck still overlaps the slot row
           vertically — a 112px rail leaves the deck's painted edge 2.6px clear
           of slot five and a 120px rail puts it through it.

           A THIRD claimant used to set the vmin coefficient: the reaction pill,
           which dodged clear of the whole rail whenever a summoner carried
           effects, so the rail's left edge plus 38px of face had to stay off
           the board. THAT CLAIMANT IS GONE — the plate no longer sits on the
           crest, so the pill no longer dodges anything and its rules were
           deleted (see thinking-indicator.css). The coefficient is left at
           34vmin rather than re-solved: it is now over-provisioned rather than
           tight, and the deck anchor that depends on it is a shipped,
           separately-tested geometry that a re-solve would move for no gain.

           WHAT THE RAIL STILL DOES: it anchors the deck stack
           (`right: calc(column + rail + 8px)`, indicators.css) and it caps
           `--phone-status-side-lane` below. It no longer sizes the plate — the
           lane does, and the lane is bounded by the board, not by this token.
           34vmin operates between the stops (93.5px at 275 through 133.3px at
           392): the floor binds on the short boxes, the cap on the tall ones. */
        --phone-status-rail-width: clamp(112px, calc(34 * var(--mf-dvmin)), 128px);

    }

    .status-indicator {
        width: max-content;
        max-width: min(
            var(--phone-status-rail-width),
            calc(100vw - var(--mf-safe-left) - var(--mf-safe-right) - 16px)
        );
        /* THE SHARED LANDSCAPE-PHONE PLACEMENT, which the SIDE LANE below
           replaces on every box wide enough to hold one. What remains here is
           the fallback for the 667-wide class, where no lane exists — see the
           `min-width: 701px` block for the measurements. Clamped-centred on the
           crest: `-50%` is half the PLATE's width and `<crest>/2 - 100%` puts
           its right edge on the crest's, and `min()` takes whichever moves it
           further left, so an ordinary status centres and an oversized one
           stops at the crest's right edge instead of clipping off screen. */
        top: 4px;
        right: auto;
        bottom: auto;
        left: 50%;
        transform: translateX(min(-50%, calc(var(--phone-summoner-portrait-width, var(--phone-command-banner-width)) / 2 - 100%)));
        flex-flow: row wrap;
        /* THE REPORTED DEFECT: "their text is not centered."
           This was `flex-end`. The plate is `width: max-content` under a
           `max-width`, so as soon as the effects are wider than the cap the box
           snaps to the FULL cap and `justify-content` decides where each
           wrapped line sits inside it — every line went flush right, leaving a
           ragged left edge inside a visibly wider plate. Measured on the
           owner's device: "Mind-picked" (59px) and "Secrets exposed" (81px)
           both ending at x=795 in a 112px box.

           `text-align: center` was already declared and could never fix it: it
           centres inline content INSIDE a chip, and each chip is a block that
           has already shrink-wrapped its own line. Nor can the plate be made to
           shrink-wrap its widest wrapped line — `max-content` is by definition
           the UNWRAPPED width, and CSS exposes no "widest line" sizing. So the
           honest fix is to centre the lines, and it is one word. */
        justify-content: center;
        align-items: flex-start;
        padding: 1px;
        gap: 1px;
        border: 1px solid rgba(234, 199, 97, 0.34);
        border-radius: 5px;
        background: linear-gradient(
            180deg,
            rgba(12, 7, 20, 0.78),
            rgba(12, 7, 20, 0.68)
        );
        box-shadow:
            inset 0 1px 0 rgba(255, 255, 255, 0.08),
            0 2px 6px rgba(0, 0, 0, 0.58);
        font-size: clamp(10px, calc(3 * var(--mf-dvmin)), 12px);
        line-height: 1.15;
    }

    .status-effect-chip {
        flex: 0 1 auto;
        /* Keep the shared ribbon's edge inset as the padding budget. A second
           inset on every chip costs a full CJK glyph on the narrowest rail,
           forcing an otherwise three-line 40-glyph effect into the resource
           sockets below. */
        /* A 1px VERTICAL allowance, and zero horizontal — see below for why the
           horizontal inset must stay at zero.

           Firefox gives Han and Kana glyphs a taller line box than Chrome or
           WebKit at the same line-height, so every Japanese and Chinese status
           effect overflowed its chip by exactly 2px on all five landscape-phone
           page boxes, in Firefox only, on the shipped build. With `padding: 0`
           the chip box is precisely its content box, so any cross-engine line-box
           difference clips immediately.

           A `:lang()`-scoped line-height bump was tried first and does not work:
           effect text can be CJK while the document language is not (a custom
           summoner name in an English UI), so the allowance has to be
           script-independent. Flat padding is also cheaper than a line-height
           increase, which multiplies per wrapped line — and the 40-glyph
           worst-case ledger wraps to three. */
        padding: 1px 0;
        /* NO ACCENT EDGE ON A PHONE — and it is REMOVED, not narrowed.
           Reported twice from the owner's device, the second time as: "enemy
           status on mobile ... an initial artifact that looks like a cursor,
           like a | kind of thing."

           The base rule gives every chip `border-left: 2px solid
           var(--status-effect-accent)` as the left edge of an opaque rounded
           pill. THIS TIER DELETES THE PILL — `background: transparent`,
           `border-radius: 0`, `box-shadow: none` — and the padding above is
           pinned to ZERO horizontally for reasons that are not negotiable. So
           the edge had nothing left to edge: it rendered as a bare hairline
           standing at zero distance from the first glyph, in the same hue as
           the word behind it. Measured on the served build, at every landscape
           page box: 1px wide, 13.5px tall, 0px from the ink. That is a text
           cursor, and the eye reads it as one.

           IT COULD NOT BE FIXED BY MOVING IT. Clearance would take
           `padding-left`, and the block above measures what that costs — a full
           CJK glyph on the narrowest rail, which pushes a three-line ledger into
           the resource sockets. So the edge goes.

           NO COLOUR INFORMATION IS LOST. The base rule paints the WORD from the
           effect's accent (`color: var(--status-effect-text, ...)`, locked by
           statusColorParity.test.js), and that rule's own comment calls the word
           the primary channel: "The WORD carries it — tinting only the edge left
           every status the same cream and taught the player nothing." The edge
           was the secondary channel, and only on the tier that still draws a
           pill for it to sit on. Desktop and tablet are untouched: there the
           chip keeps its 7px inset, opaque fill and 5px radius, where the same
           border reads as an accent rather than a caret.

           The first round of this report read the mark as a literal `|`
           CHARACTER and widened the segmentation to `/[;|]/` in indicators.js.
           That was a real leak and the fix stands — but it was never this one,
           and the caret survived it. Rendered oracle:
           summoner-status-placement.spec.js, "no status chip paints a caret
           before its text"; declaration guard:
           summonerStatusReadability.test.js. */
        border-left: none;
        border-radius: 0;
        background: transparent;
        box-shadow: none;
    }

    /* EACH PLATE GROWS AWAY FROM ITS OWN DECK STACK, AND FROM THE PAGE EDGE.
       ======================================================================
       The side lane is shared with the deck stacks, and the two decks sit at
       OPPOSITE vertical extremes — the opponent's is pinned to the top edge and
       hangs 40% off it, the player's to the bottom edge and hangs 40% off that.
       So each seat is anchored to the crest edge nearest its own free room and
       grows toward the middle of the lane, which is where two growing plates
       should meet last.

       THE PLAYER GROWS UPWARD FROM THE DISC ROW. Its lower edge sits level with
       the top of its own resource sockets — the same `clamp(24px, 7.4vmin,
       32px)` the discs themselves use in indicators.css, so the two track each
       other by construction rather than by measurement. Two properties follow
       and neither depends on the deck's or the page's dimensions:

         * the deck stack is BELOW that line at every box (measured clearance
           6.4-8.7px across all six), and the plate grows away from it, so no
           ledger of any length can reach the deck;
         * the plate's lower edge is above the crest's lower edge, which is
           above the page box, so no ledger of any length can fall off the
           bottom of the screen.

       Both were real. A first pass anchored this plate at the crest's TOP and
       grew it DOWN, which gave it only `crestTop -> deckTop` (70.8-78.4px) of
       room and `crestTop -> pageBottom` (112.2px at 667x275) before the page
       edge. At the narrowest box a 77-character effect wraps to 109.5px in that
       box's 57.4px lane: it reached 27.2px into the deck in every engine, and
       in FIREFOX — whose line boxes run taller — it crossed the bottom of the
       page box outright. Growing the other way makes both impossible instead of
       merely unlikely.

       THE OPPONENT HANGS BELOW ITS CREST, for the mirror reason. Bottom-
       anchoring it is the natural symmetry and was measured first: it leaves
       only 44.8px between the crest's lower edge and its deck's trailing edge,
       and the owner's own two-effect status already wraps to 52px in the
       narrowest lane — 7.2px straight through the deck. Hanging it below the
       crest opens the column down toward the player's plate instead:

           667x275  138.8px     844x288  151.8px     915x336  187.6px
           844x280  143.8px     932x300  163.7px     852x344  192.4px

       of shared lane, which the two plates divide between them.

       The property the old on-crest placement was built for survives: a plate
       that wraps does not MOVE, it only extends. It simply no longer has to buy
       that by covering the summoner. */
    /* The shared fallback anchor, kept for the 667-wide class only (the side
       lane below overrides it everywhere else). Bottom-anchored `6px + the
       disc` above the crest's lower edge, so the plate clears the resource
       sockets by construction at any crest height and grows upward when it
       wraps rather than down into them. */
    #opponent-status-indicator,
    #player-status-indicator {
        top: auto;
        right: 0;
        bottom: calc(6px + clamp(24px, calc(7.4 * var(--mf-dvmin)), 32px));
    }

    /* THE +12px IS NO LONGER A TEXT SHELF, AND IS KEPT ANYWAY. READ THIS BEFORE
       DELETING IT.
       It was reserved so a four-line status had somewhere to go that was not
       the resource sockets. The status has left the crest entirely, so that
       job is finished — but the 12px is not dead, it changed owner:

         * IT IS WHAT MAKES THE CREST ONE SIZE. Granting the room only to a
           status-BEARING portrait made the portrait resize as effects came and
           went — 73px to 85px at 932x300, measured — and everything laid out
           after it moved by those 12px every time: "also changing the enemy
           summoner status moves the return to lobby button". Reserving it
           unconditionally is what retired that report, and removing it now
           would not reintroduce the resize, but it WOULD move the crest, the
           discs, the nameplate, the End Turn seam and this file's own lane
           anchors on every phone at once.
         * IT IS ALSO 12px OF SUMMONER ART. The well is `background-size: cover`
           at `50% 0%`, so a shorter crest crops the bust tighter — the opposite
           of the direction the reported defect was about.

       So it stays, deliberately, as crest geometry rather than as status
       reservation. Locked by summoner-status-placement.spec.js, "a status
       change reflows nothing". */
    /* Sized from the CREST token, not the command banner. The two were the
       same number until the rail needed a seam to live in: on a 288px page box
       the two summoner clusters owned 265px of it, so neither the Volume+End
       Turn stack nor the exit had anywhere legal to sit and the seat search
       wandered onto the board and the storyboard. The crest is now narrower
       than the buttons; this rule has to follow it or the ID selector here
       silently keeps the old height and the seam never opens.
       The +12px is unchanged and still unconditional — see above for what it
       now buys, which is no longer the status plate. */
    #player-portrait,
    #opponent-portrait {
        height: calc(
            var(--phone-summoner-portrait-width, var(--phone-command-banner-width))
            * 23 / 31 + 12px
        );
    }
}

/* ============================================================================
   THE SUMMONER STATUS SIDE LANE
   ============================================================================
   Reported on the owner's physical iPhone 13 (page box 844x280, insets
   0/47/20/47): "summoner status effects are badly placed. their text is not
   centered. and even worse, it covers the summoner faces/profiles."

   The CENTRING half is fixed for every landscape phone, in the shared block
   above. This block fixes the other half: the plate leaves the crest for the
   column immediately left of it — the column the deck stack already occupies at
   its far vertical ends.

   WHY `min-width: 701px`, AND WHY THAT IS NOT A ROUND NUMBER PULLED FROM AIR
   -------------------------------------------------------------------------
   The lane is the band between the board's rightmost slot and the crest's left
   edge, and it is not the same size on every page box. A phone viewport is the
   PAGE BOX, and every profile has TWO — bars showing and bars hidden, because
   the URL bar collapses mid-scroll. All twelve, measured:

       profile / bar state           box        band
       iphone-15-pro-max  viewport   932x300   181.8px
       pixel-7            viewport   915x336   165.3px
       iphone-13          viewport   844x280   156.1px
       pixel-7            barsHidden 915x392   147.5px
       iphone-13/tabstrip viewport   844x288   141.6px
       iphone-15-pro-max  barsHidden 932x396   137.2px
       iphone-15-pro      viewport   852x344   122.4px
       iphone-15-pro      barsHidden 852x364   115.8px
       iphone-13          barsHidden 844x376   115.4px
       iphone-13/tabstrip barsHidden 844x376   104.0px
       iphone-SE          viewport   667x275    70.1px
       iphone-SE          barsHidden 667x335    43.7px  <- NO LANE EXISTS HERE

   At 667x335 both squeezes peak at once: the taller box grows the BOARD (slot
   row ends at 468.8 rather than 452.9) and grows the CREST (110.6px rather than
   100px), leaving 43.7px between them. After the 6px crest seam and a board
   seam that is ~33px — narrower than one wrapped word at the 10px type floor.
   So the 667-wide class keeps the shared on-crest placement rather than being
   given an unreadable one, and it keeps it in BOTH bar states so the plate
   cannot jump placement mid-scroll.

   A first pass shipped the lane at every phone tier with this same `32vw` floor
   fitted to the six bars-VISIBLE boxes only. It drove the plate 9.2px through
   slot five at 667x335 — caught by mobile-battle.spec.js, the only suite that
   sweeps both bar states. Fitting a floor to half the matrix is the whole
   failure, and it is why the boundary here is a media query rather than a
   cleverer formula: 43.7px cannot be made to work.

   Above 700px the band is 104-182px and the floor holds with 22.4-63.8px of
   margin at all ten boxes.
   ========================================================================== */
@media (orientation: landscape) and (max-height: 560px)
    and (min-width: 701px) and (max-width: 932px) {
    :root {
        /* THE SEAM BETWEEN THE PLATE AND THE CREST. Small on purpose: every
           pixel here is taken from the plate's own width. */
        --phone-status-side-gap: 6px;

        /* The lane is bounded by the BOARD, not by the status rail.
           The board is exactly viewport-centred at every profile (measured:
           slot centre == vw/2 to the pixel) and its right edge never passes
           66.1% of the page box across the ten boxes this block serves, so
           `32vw` in from the right edge is right of slot five everywhere. The
           rail stays the cap so a wide page box cannot grow a runaway plate.

           THE BOARD'S WIDTH IS NOT DERIVABLE HERE, so it is not derived: this
           is a measured floor. summoner-status-placement.spec.js asserts the
           plate clears every board slot at every page box in all three engines,
           and mobile-battle.spec.js sweeps both bar states. If the board grows,
           those fail loudly instead of this failing silently.

           The `var()` fallbacks are load-bearing, not decoration: an invalid
           `var()` invalidates the WHOLE declaration with no fallback, and a
           lost `max-width` here would let the plate span the board. */
        --phone-status-side-lane: min(
            var(--phone-status-rail-width),
            calc(
                32vw
                - var(--phone-summoner-column-right, 44px)
                - var(--phone-summoner-portrait-width, 100px)
                - 12px
            )
        );
    }

    .status-indicator {
        max-width: min(
            var(--phone-status-side-lane),
            calc(100vw - var(--mf-safe-left) - var(--mf-safe-right) - 16px)
        );
        /* BESIDE THE CREST, NEVER ON IT.
           `right: calc(100% + gap)` measures 100% of the CONTAINING BLOCK — the
           crest itself — so the plate's right edge lands exactly one seam left
           of the crest's left edge whatever the crest's width resolves to. No
           token is read for the horizontal anchor at all, which is the point:
           both previous placements aimed at a hardcoded idea of where the
           crest's edge was, and both drifted when the crest was retokenised. */
        top: auto;
        right: calc(100% + var(--phone-status-side-gap, 6px));
        bottom: auto;
        left: auto;
        transform: none;
    }

    /* EACH PLATE GROWS AWAY FROM ITS OWN DECK STACK, AND FROM THE PAGE EDGE.
       The two decks sit at opposite vertical extremes — the opponent's pinned
       to the top edge hanging 40% off it, the player's to the bottom edge — so
       each plate is anchored to the crest edge nearest its own free room and
       grows toward the middle of the lane, where two growing plates should meet
       last.

       THE PLAYER GROWS UPWARD FROM ITS DISC ROW. Its lower edge sits level with
       the top of its own resource sockets — the same clamp the discs use in
       indicators.css, so the two track each other by construction. Two
       properties follow, and neither depends on the deck's or the page's size:
       the deck is below that line at every box (6.4-8.7px clear) and the plate
       grows away from it, so no ledger of any length can reach the deck; and
       the plate's lower edge is above the crest's lower edge, which is above the
       page box, so no ledger can fall off the bottom of the screen.

       Both were earned. A pass anchored this plate at the crest's TOP growing
       DOWN, which left only `crestTop -> deckTop` (70.8-78.4px) and
       `crestTop -> pageBottom` (112.2px at the narrowest box): a 77-character
       effect reached 27.2px into the deck in every engine, and in FIREFOX —
       taller line boxes — crossed the bottom of the page box outright.

       THE OPPONENT HANGS BELOW ITS CREST, for the mirror reason. Bottom-
       anchoring it leaves only 44.8px before its own deck, which the owner's
       own two-effect status already overruns by 7.2px. */
    #player-status-indicator {
        top: auto;
        right: calc(100% + var(--phone-status-side-gap, 6px));
        bottom: clamp(24px, calc(7.4 * var(--mf-dvmin)), 32px);
    }

    #opponent-status-indicator {
        top: 100%;
        right: calc(100% + var(--phone-status-side-gap, 6px));
        bottom: auto;
    }
}
