/* ==========================================================================
   Ramp phone layer (R5.0b). The phone rules of components.css, moved here
   unchanged by the R5.0b move commit (docs/design/four-doors-remedy/audit/
   build-batch-9/r5/r5.0b-notes.md), and the shared phone fixes that follow.
   Linked directly after components.css by every template that links it, so
   the cascade order is the one these rules had. Tokens only: no new px
   literal (check_token_literals); the bar height is --bar-clearance.
   Family css stays in the family files. Budget: tests/test_r5_shared.py.
   ========================================================================== */

/* FP-FA-11: §9's 44px touch-target floor applies to EVERY interactive
   control at phone widths, not only `.btn--lg`: `sm`/`md` stay the
   visually-distinct desktop scale but gain the same mobile floor as
   `.field input`/`.org-tab` above (min-height, so the smaller box just
   grows its hit area rather than losing the size distinction entirely). */
@media (max-width: 639.98px) {
  .btn--sm, .btn--md { min-height: 44px; }
}
/* R5.0c: a small button is 44px on a touch screen at any width (a landscape phone is 844px wide). The 40px .btn--md is the desktop scale
   the tap rule accepts from 640px up, so it is left alone there. */
@media (pointer: coarse) {
  .btn--sm, .field :is(input, select):not([type="checkbox"], [type="radio"]), select.select, .input { min-height: var(--control-target-min); } /* R5.0d: fields too */
}

@media (max-width: 639.98px) {
  /* FP-FA-11: the bare `.input` class (used ~26 templates OUTSIDE a
     `.field` wrapper, see the C-06 note in components.css) was missing from this
     floor, so those controls stayed at the desktop 40px box (measured
     26px on flight-prep's ICAO inputs, 23px on the flight-rules select,
     since `.input` alone carries no explicit height at all, only
     `.field input`/`.field select` do). Add `.input` to the same floor. */
  .field input, .field select, select.select, .input { height: 44px; }
}

@media (max-width: 30rem) {
  .page-header__actions .btn { white-space: normal; height: auto; min-height: var(--control-target-min); text-align: center; }
  .crumb-row { column-gap: var(--space-3); }
}

@media (max-width: 639.98px) {
  .drawer {
    top: auto;
    left: 0;
    width: 100%;
    max-height: 90vh;
    max-height: 90dvh;
    border-radius: var(--radius-sm) var(--radius-sm) 0 0;
    padding: var(--space-4);
    padding-bottom: calc(var(--space-4) + env(safe-area-inset-bottom));
    transform: translateY(100%);
  }
  .drawer.is-open { transform: translateY(0); }
  .drawer input:not([type="hidden"], [type="radio"], [type="checkbox"]), .drawer select, .drawer textarea,
  .drawer button, .drawer a { min-height: var(--control-target-min); }
}

@media (max-width: 639.98px) {
  .stepper { flex-direction: column; align-items: flex-start; gap: var(--space-3); }
  .stepper__step { flex-direction: row; align-items: center; width: 100%; }
  .stepper__step::before { display: none; }
  .stepper__label { margin-top: 0; margin-left: var(--space-3); max-width: none; text-align: left; }
}

/* §9 touch-target floor: interactive pill tabs are ≥44px at phone widths. */
@media (max-width: 639.98px) {
  .org-tab { height: var(--control-target-min); padding: 0 var(--space-4); }
}

/* FP-FA-11 (R5.0c): an inline glossary term in running text is a 44px target, and the target is the trigger's own box (it was an
   invisible ::before, which the checks reported as a spill of the box and as a 17px target). The box grows to 44px wide at the
   narrowest (a long term already is) and 44px tall, and a negative block margin gives the height back to the line, so the line
   does not grow; a three-letter term gains at most 16px of width in the sentence. The focus ring hugs the text line, drawn on a
   ::after that takes no pointer events, so it never covers the line above. */
@media (max-width: 639.98px), (pointer: coarse) {
  .gloss__trigger {
    display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box; position: relative;
    min-width: var(--control-target-min); min-height: var(--control-target-min);
    margin-block: calc((1lh - var(--control-target-min)) / 2);
  }
  .gloss__trigger:focus-visible { outline: none; }
  .gloss__trigger:focus-visible::after {
    content: ""; position: absolute; inset-block: calc((100% - 1lh) / 2); inset-inline: 0;
    outline: var(--space-half) solid var(--color-link); outline-offset: var(--space-half); pointer-events: none;
  }
}

@media (max-width: 639.98px) {
  /* Two lines in every row: name and status, then fact and door. R5.0b (PLAN 2.5): the status column is at most half the row
     and never leaves the fact under 8rem, so a long status wraps inside its own half and never squeezes the fact. */
  .list-row { grid-template-columns: minmax(0, 1fr) fit-content(max(var(--control-target-min), min(50%, calc(100% - 8rem - var(--space-3))))); row-gap: var(--space-1); }
  .list-row__name { grid-area: 1 / 1; }
  .list-row__status { grid-area: 1 / 2; justify-self: end; }
  .list-row__fact { grid-area: 2 / 1; }
  .list-row__action { grid-area: 2 / 2; }
  :where(.list-row:has(> .list-row__status:empty)) > .list-row__name { grid-column: 1 / -1; }
  :where(.list-row:has(> .list-row__action:empty)) > .list-row__fact { grid-column: 1 / -1; } :where(.list-row:has(> .list-row__fact:empty):has(> .list-row__status:empty)) > .list-row__action { grid-area: 1 / 2; } :where(.list-row:has(> .list-row__fact:empty):has(> .list-row__status:empty)) > .list-row__name { grid-column: 1; } /* Batch 11: a row of name and door keeps its door at the row right */
  .list-row__action a, .list-row__action button { display: inline-flex; align-items: center; min-height: var(--control-target-min); }
}
/* A narrow card or drawer reads its rows as on a phone (B1). */
@container rows (max-width: 40rem) {
  .list-row { grid-template-columns: minmax(0, 1fr) fit-content(max(var(--control-target-min), min(50%, calc(100% - 8rem - var(--space-3))))); row-gap: var(--space-1); }
  .list-row__name { grid-area: 1 / 1; }
  .list-row__status { grid-area: 1 / 2; text-align: end; }
  .list-row__fact { grid-area: 2 / 1; }
  .list-row__action { grid-area: 2 / 2; }
  :where(.list-row:has(> .list-row__status:empty)) > .list-row__name, :where(.list-row:has(> .list-row__action:empty)) > .list-row__fact { grid-column: 1 / -1; } :where(.list-row:has(> .list-row__fact:empty):has(> .list-row__status:empty)) > .list-row__action { grid-area: 1 / 2; } :where(.list-row:has(> .list-row__fact:empty):has(> .list-row__status:empty)) > .list-row__name { grid-column: 1; }
  .table--list-rows, .table--list-rows > tbody { display: block; }
  .table--list-rows > thead { display: none; }
  .table--list-rows > tbody > tr { display: grid; grid-template-columns: minmax(0, 1fr) fit-content(max(var(--control-target-min), min(50%, calc(100% - 8rem - var(--space-3))))); gap: var(--space-2) var(--space-3); padding: var(--space-3) var(--cell-px); border-top: var(--rule-width) solid var(--color-border); }
  .table--list-rows > tbody > tr > td { display: block; height: auto; min-height: 0; padding: 0; border: 0; max-width: 100%; }
  .table--list-rows > tbody > tr > [data-slot="name"] { grid-area: 1 / 1; }
  .table--list-rows > tbody > tr > [data-slot="status"] { grid-area: 1 / 2; justify-self: end; }
  .table--list-rows > tbody > tr > [data-slot="fact"] { grid-area: 2 / 1; }
  .table--list-rows > tbody > tr > [data-slot="action"] { grid-area: 2 / 2; justify-self: end; }
  .table--list-rows > tbody > tr > [data-slot="action"]:empty { display: none; }
  .table--list-rows > tbody > tr:has(> [data-slot="action"]:empty) > [data-slot="fact"] { grid-column: 1 / -1; }
}

@media (max-width: 639.98px) {
  .table--list-rows, .table--list-rows > tbody { display: block; }
  .table--list-rows > thead { display: none; }
  .table--list-rows > tbody > tr {
    display: grid; grid-template-columns: minmax(0, 1fr) fit-content(max(var(--control-target-min), min(50%, calc(100% - 8rem - var(--space-3)))));
    gap: var(--space-2) var(--space-3); padding: var(--space-3) var(--cell-px);
    border-top: var(--rule-width) solid var(--color-border);
  }
  .table--list-rows > tbody > tr > td {
    display: block; height: auto; min-height: 0; padding: 0; border: 0;
    white-space: normal; max-width: 100%;
  }
  .table--list-rows > tbody > tr > [data-slot="name"] { grid-area: 1 / 1; }
  .table--list-rows > tbody > tr > [data-slot="status"] { grid-area: 1 / 2; justify-self: end; }
  .table--list-rows > tbody > tr > [data-slot="fact"] { grid-area: 2 / 1; }
  .table--list-rows > tbody > tr > [data-slot="action"] { grid-area: 2 / 2; justify-self: end; }
  .table--list-rows > tbody > tr > [data-slot="action"]:empty { display: none; }
  .table--list-rows > tbody > tr:has(> [data-slot="action"]:empty) > [data-slot="fact"] { grid-column: 1 / -1; }
  .table--list-rows > tbody > tr > [data-slot="action"]:has(details[open]) { grid-column: 1 / -1; grid-row: 3; justify-self: stretch; }
  .table--list-rows > tbody > tr.table__summary { display: block; }
  .table--list-rows a, .table--list-rows button, .table--list-rows summary { display: inline-flex; align-items: center; min-height: var(--control-target-min); max-width: 100%; white-space: normal; }
  .table--list-rows input:not([type="hidden"], [type="radio"], [type="checkbox"]), .table--list-rows select { min-height: var(--control-target-min); max-width: 100%; box-sizing: border-box; }
  .table--list-rows .pill { white-space: normal; }
}

@media (max-width: 639.98px) {
  .fact-row { grid-template-columns: minmax(0, 1fr) auto; row-gap: var(--space-1); }
  .fact-row > dt, .fact-row > dd:last-child:not(:nth-child(3)) { grid-column: 1 / -1; } /* Batch 10: a row with an action wraps, so at 200 percent text the action drops under its value instead of squeezing it */ .fact-row:has(> .fact-row__action) { display: flex; flex-wrap: wrap; align-items: baseline; column-gap: var(--space-3); } .fact-row:has(> .fact-row__action) > dt { flex: 1 0 100%; } .fact-row:has(> .fact-row__action) > dd:not(.fact-row__action) { flex: 1 1 8rem; } .fact-row:has(> .fact-row__action) > .fact-row__action { flex: 0 0 auto; margin-inline-start: auto; }
}
/* Delta-1 M1: a phone in landscape (coarse, under 500px tall) is a phone too,
   the same query as the Forge read-only phone (forge-shell.css). */
@media (max-width: 639.98px), ((max-height: 499.98px) and (pointer: coarse)) {
  .empty[data-phone-action] .empty__action > :not([data-empty-phone]) { display: none; }
  .empty[data-phone-action] [data-empty-phone] { display: inline-flex; }
}

@media (max-width: 639.98px) {
  .table--list-rows > tfoot, .table--list-rows > tfoot > tr, .table--list-rows > tfoot > tr > td { display: block; }
}

/* R5.0b: the stepper's phone summary is hidden from 640px up, where the list shows whole (PLAN 2.8). */
.stepper__summary { display: none; }

@media (max-width: 639.98px) {
  .list-row a, .list-row button, .table--list-rows a, .table--list-rows button,
  .table--list-rows summary, .table--list-rows input:not([type="hidden"], [type="radio"], [type="checkbox"]),
  .table--list-rows select { min-width: var(--control-target-min); min-height: var(--control-target-min); box-sizing: border-box; }
  /* Cascade restorations (R5.0b move review): two ties that components.css used to win by coming later. The disclosure marker on a
     row's action summary inside a list-row table (the .table--list-rows summary rule above is inline-flex), and a choice chip's input
     filling its chip inside a .field. */
  .table--list-rows .row-actions > summary { display: list-item; }
  .choice-chips__option input { height: 100%; }
  /* R5.0b shell header (PLAN 2.3): the school's name wraps to a second line before it is cut (C1 r2); the Me sheet says it whole. R6.5 r4: a header under 16rem (320 at 200% text) gives the name its own full-width line under the bar, never a stub, never gone. */
  .shell-header > .shell-identity[data-full-in], .shell-identity__name { min-width: 0; overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow-wrap: break-word; }
  .shell-tenant { min-width: 0; } @container shell (max-width: 16rem) { .shell-header > .shell-identity { order: 10; flex: 1 0 100%; } }
  /* C5 r2 stepper (x24): one row, a numeral per step, the current step also names itself (it wraps on word boundaries when the row is full); the other labels stay for assistive technology. */
  .stepper ol { flex-direction: row; flex-wrap: wrap; align-items: center; gap: var(--space-1); } .stepper li[data-step-state="current"] { flex: 1 1 auto; min-width: 0; } .stepper li > :is(a, span) { min-width: var(--control-target-min); justify-content: center; } .stepper:has([data-step-state="current"]) li:not([data-step-state="current"]) .stepper__text { position: absolute; width: var(--rule-width); height: var(--rule-width); overflow: hidden; clip-path: inset(50%); white-space: nowrap; } @media (min-width: 23rem) { .stepper ol { flex-wrap: nowrap; } .stepper li[data-step-state="current"] > :is(a, span) { align-items: center; } } /* bug pass A: six steps hold one row at 390, the current label wraps inside it */
  .stepper li[data-step-state="current"] > :is(a, span) { justify-content: flex-start; } body:has(.drawer.is-open) .page-header__actions .btn--primary { visibility: hidden; } /* C5 r2 (x01): a page primary is not drawn behind its own open sheet */
  /* R5.0b rows (PLAN 2.5): a plain table whose cells carry data-label stacks into label and value blocks (MB-D 4.6), its head kept for assistive technology. */
  .table:has(td[data-label]), .table:has(td[data-label]) > tbody, .table:has(td[data-label]) > tbody > tr { display: block; }
  .table:has(td[data-label]) > thead { position: absolute; width: var(--rule-width); height: var(--rule-width); overflow: hidden; clip-path: inset(50%); } .table:has(td[data-label]) > thead :is(tr, th) { display: block; height: var(--rule-width); padding: 0; border: 0; overflow: hidden; } /* C7 r2: the clipped head's cells keep no box that could sit over a pinned foot */
  .table:has(td[data-label]) > tbody > tr { padding-block: var(--space-3); border-top: var(--rule-width) solid var(--color-border); }
  .table:has(td[data-label]) > tbody > tr > td { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); gap: var(--space-3); height: auto; padding-block: var(--space-1); border: 0; }
  .table:has(td[data-label]) > tbody > tr > td::before { content: attr(data-label); color: var(--color-text-secondary); }
  /* R5.0b footer (PLAN 2.1): the beta line, then the version, terms and status as one group: two lines, no dot between them,
     so no word is left alone and no line starts with a dot. */
  .app-footer__keep { display: flex; flex-wrap: wrap; justify-content: center; }
  .app-footer__keep > * { white-space: nowrap; }
  .app-footer__dot { display: none; }
  .app-footer > div > span:first-child { display: block; }
}

/* R5.0b bar clearance (PLAN 2.1): under 768px the fixed bottom bar owns --bar-clearance (tokens.css), and
   the content, the footer and a focused control all clear it by that one value. */
@media (max-width: 767px) {
  html:has(body:is([data-shell="school"], [data-shell="student"], [data-shell="forge"])) {
    scroll-padding-bottom: calc(var(--bar-clearance) + var(--space-2));
  }
  /* R5.0c: a bar label shrinks to its cell (R-0142: "Account" and "Manage" left their cell at 200 percent text). */
  .tabbar > a { font-size: min(var(--text-xs), 4.2vw); }
  .app-main, .forge-main-content { padding-bottom: calc(var(--bar-clearance) + var(--space-6)); }
  .app-footer { padding-bottom: calc(var(--bar-clearance) + var(--space-4)); }
}

/* --- R5.0b strips: one row that scrolls inside itself (MB-D 4.8; reverses the batch-5 wrap) ------------
   shell-navigation.js adds a chevron door at each end that still holds tabs. A door takes no flow
   space (its negative margin cancels its box and the gap), so adding or removing it moves no tab; it
   covers the edge of the tab it points at. */
/* A strip contributes nothing to its parent's intrinsic width (width 0) and fills the parent anyway (min-width 100%), so it can never
   size a wrapping header, a grid track or a flex row to its tabs, at any text size. Its tabs scroll inside it. */
.subnav { width: 0; min-width: 100%; max-width: 100%; scroll-padding-inline: var(--control-target-min); } /* a focused tab scrolls clear of the doors */
.subnav__tab { flex: none; max-width: calc(100vw - 2 * var(--space-4) - 2 * (var(--control-target-min) + var(--space-1))); white-space: normal; text-align: center; } /* R5.0d: a tab wider than a phone's strip between its doors wraps its words, never cut (vw, not %: a % cap follows the strip through a relayout and moves the current tab) */
.subnav__more { position: sticky; z-index: 1; flex: none; display: inline-flex; align-items: center; justify-content: center; width: var(--control-target-min); min-height: var(--control-target-min); padding: 0; border: 0; background: var(--color-bg); color: var(--color-link); cursor: pointer; }
.subnav__more--start { left: 0; margin-inline-end: calc(-1 * (var(--control-target-min) + var(--space-1))); box-shadow: inset calc(-1 * var(--rule-width)) 0 0 var(--color-border); }
.subnav__more--end { right: 0; margin-inline-start: calc(-1 * (var(--control-target-min) + var(--space-1))); box-shadow: inset var(--rule-width) 0 0 var(--color-border); }
.subnav__more--start svg { transform: scaleX(-1); }

/* --- R5.0b bottom bars: the current item carries a rule above it as well as colour and weight, on the School, Student and Forge bars --- */
.tabbar > a[aria-current] { box-shadow: inset 0 var(--accent-rule) 0 var(--color-link); }

/* --- R5.0b targets (PLAN 2.7): a radio or checkbox is drawn at --control-glyph and never stretched or squeezed;
   its label is the 44px target (MB-D 7.1; the R3.9 rule, measured on the label by every capture helper). --- */
:where(input[type="radio"], input[type="checkbox"]) { flex: none; width: var(--control-glyph); height: var(--control-glyph); min-width: 0; min-height: 0; }
:where(label:has(> input[type="radio"], > input[type="checkbox"]):not(:has(> select, > textarea, > input:not([type="radio"], [type="checkbox"])))) { display: flex; align-items: center; gap: var(--space-2); }
label:has(> input[type="radio"], > input[type="checkbox"]) { min-height: var(--control-target-min); min-width: var(--control-target-min); }
input[type="radio"] + label, input[type="checkbox"] + label { display: inline-flex; align-items: center; min-height: var(--control-target-min); min-width: var(--control-target-min); }

/* --- R5.0b sheets and drawers (PLAN 2.4): the body scrolls above its foot, a focused control scrolls clear of the
   foot, and a scrolled-out body never drags the page behind it. At 844x390 touch a drawer clears the safe areas. --- */
.drawer__body, .sheet__body, .credential-sheet__body { overscroll-behavior: contain; scroll-padding-bottom: var(--sheet-foot-room); }
@media (max-height: 499.98px) and (pointer: coarse) {
  .drawer { padding-block: max(var(--space-4), env(safe-area-inset-top)) max(var(--space-4), env(safe-area-inset-bottom)); padding-right: max(var(--space-6), env(safe-area-inset-right)); }
}

/* --- R5.0b identifiers (PLAN 2.6): a registration, a code or a mono chip never breaks inside; it moves to its own line whole.
   This beats the overflow-wrap: anywhere that rows, drawers and records set on their cells. Opt-in: a chip, a badge, the record title, and
   `.mono--id` (a registration, an ICAO ident: the templates mark them). Every other .mono, in a row or not (an email, a UUID, a
   URL, a path, a certificate number), breaks like any text. --- */
.chip.mono, .badge.mono, .page-header__title.mono, .mono--id { white-space: nowrap; overflow-wrap: normal; word-break: keep-all; }

/* --- R5.0b counts: a count is a door into the queue that produced it, so at every width it is a 44px target that keeps its
   line's height (the .door recipe). A count in a .card__meta line keeps that line's own rule (R3.9: a sentence link is
   inline, an items link is a 44px box); the mx filter row sizes its own counts. --- */
a[data-count]:not(.card__meta a, .mx-filters a) { display: inline-flex; align-items: center; max-width: 100%; min-height: var(--control-target-min); margin-block: calc((1lh - var(--control-target-min)) / 2); }

/* --- R5.0c stacked rows (R5.1 D7, promoted from eleven page sheets): in a `rows` container under 19rem a row stacks, name, state,
   fact, door, each the row's width, nothing hidden. rem against the container (px): 19rem is 304px at 100 percent text (a 320 phone's
   286px row stacks, a 360 phone's 326px does not) and 608px at 200 percent. A viewport query in rem cannot say this. --- */
@container rows (max-width: 19rem) {
  .list-row { grid-template-columns: minmax(0, 1fr); }
  .list-row > * { grid-area: auto; justify-self: start; text-align: start; }
  .list-row > .list-row__name { order: 1; justify-self: stretch; }
  .list-row > .list-row__status { order: 2; }
  .list-row > .list-row__fact { order: 3; justify-self: stretch; }
  .list-row > .list-row__action { order: 4; }
  .list-row:has(> .list-row__action > details[open]) > .list-row__action { justify-self: stretch; }
  .list-row > .list-row__status:empty, .list-row > .list-row__action:empty { display: none; }
  .list-row .pill { overflow-wrap: normal; }
  .table--list-rows > tbody > tr { grid-template-columns: minmax(0, 1fr); }
  .table--list-rows > tbody > tr > [data-slot] { grid-area: auto; justify-self: start; text-align: start; }
  .table--list-rows > tbody > tr > [data-slot="name"] { order: 1; justify-self: stretch; }
  .table--list-rows > tbody > tr > [data-slot="status"] { order: 2; }
  .table--list-rows > tbody > tr > [data-slot="fact"] { order: 3; justify-self: stretch; }
  .table--list-rows > tbody > tr > [data-slot="action"] { order: 4; }
  .table--list-rows > tbody > tr > [data-slot="action"]:has(details[open]) { grid-area: auto; justify-self: stretch; }
  .table--list-rows > tbody > tr > [data-slot="status"]:empty, .table--list-rows > tbody > tr > [data-slot="action"]:empty { display: none; }
}

/* --- R5.0c page column and long labels (promoted from account, overview, courses, money and fleet; R5.3 R5, R5.4 R1) --- */
/* A page grid is one shrinkable column. A card's 16rem containment floor (components.css, .card:has(.list-row)) is 512px at 200 percent text,
   so an auto column took the card's floor and pushed the page past the window; a grid item may shrink below its content so a long word
   wraps inside its card. Width-independent, as the copies were. */
:is(.account-page, .overview-page, .courses-page, .money-page) { grid-template-columns: minmax(0, 1fr); }
:is(.account-page, .overview-page, .courses-page, .money-page) > :where(:not(.subnav)) { min-width: 0; } /* never a strip: its min-width 100% (above) is what fills the page */
@media (max-width: 639.98px) {
  /* A long button or door label wraps inside its container and never runs past the edge (320 at 200 percent text, R-2967); a
     one-line button keeps its 44px box (the min-height), an icon button keeps its square. */
  .btn, .door, .page-header__summary .pill { white-space: normal; max-width: 100%; text-align: start; } /* R5.0d: a record header's state too */
  .btn:not(.btn--icon) { height: auto; min-height: var(--control-target-min); padding-block: var(--space-2); text-align: center; }
}
