/* ============================================================================
   ROLLON : components.css : THE ONE COMPONENT SHEET
   ----------------------------------------------------------------------------
   FABLE_DESIGN_SCOPE_2026-08-12 §5.2 (M5). Fable counted the same component
   built up to six times across the estate: five status pills, six empty
   states, six button sets, four topbars, and a chip and a .bbtn that are
   BYTE-IDENTICAL duplicates between tour-mgmt.html and travel-board.html.

   THE RULE THIS FILE WAS BUILT UNDER: PROMOTE, NEVER REDRAW.
   Every declaration below was lifted from a named source file and line. None
   was invented, tidied or improved. Where two sources differed, the source
   Fable named as canonical wins and the difference is recorded in a comment
   above the rule, so a reviewer can see what the page will look like after it
   converts. Nothing here is a new design.

   CONTRACT : LOAD ORDER
     <link rel="stylesheet" href="/tokens.css">          <- defines the tokens
     <link rel="stylesheet" href="/assets/components.css"> <- consumes them
   This file defines NO tokens of its own by design (one owner, tokens.css). It
   reads --page --card --line --line2 --pill --pilltx --text --dim --faint
   --hoverbg --sel --blue --blue-hi --on-blue --blue-soft --blue-tx --shadow
   --bulkshadow and the status trios --grn-* --amb-* --org-*. Linking it on a
   surface that has not linked tokens.css (or does not carry its own inline
   copy of the tour-family palette) will render an unstyled component set.

   CONTRACT : CLASS SELECTORS ONLY, AND THAT IS WHY THIS IS NOW LINKABLE ANYWHERE
     This sheet keys on CLASSES only. It was not always so: the TABLE section
     used bare table / thead th / tbody td / tbody tr selectors, which meant
     linking this file on an arbitrary surface silently restyled every table on
     it. That one constraint is what kept this sheet on 8 of 37 surfaces, and it
     was 14 element-keyed rules holding 65 class-only rules hostage.
     MEASURED and SPLIT 17 Aug: the 14 moved to assets/components-table.css,
     which the tour boards link in addition to this one. This file is now safe
     on any surface. grid.html remains a deliberate exception (M8): its dense
     data interior is documented and it converts by its own careful step.

   RADIUS LANGUAGE (Fable §5.2). The estate currently ships radii of
   4, 6, 7, 8, 9, 10, 12, 14, 16, 20 and 999. The language is:
       999  pill, chip, badge, seg
       10   buttons
       12   cards
       7    nav links (assets/shell-strip.css)
       16   drawer / modal box
       4    GRID INTERIOR ONLY, a density exception, out of scope here
   The one promoted rule that does not conform is .bbtn at 9px, kept because it
   is byte-identical in both its sources and changing it would be a redraw.
   Flagged, not silently corrected.

   HOUSE RULES CARRIED: chrome is UPPERCASE and data keeps its case, so no rule
   here sets text-transform on a data cell. No emoji. No explanatory prose in
   the UI. Never an em dash in anything a person receives: a colon or a ">".
   The wordmark is only ever /rollon-wordmark-white.png, never CSS text.
   ============================================================================ */


/* HIDDEN MEANS HIDDEN, AND THE RHYTHM PASS BROKE IT (17 Aug).
   Putting every control on the scale set display:inline-flex on .seg button, .chip, .btn and the rest,
   and an explicit display ALWAYS beats the [hidden] attribute, whose only power is a UA rule of
   display:none. So the moment the components took a display, every hidden button in the estate came
   back: CAUGHT FROM EMAIL stayed on the travel board after being marked hidden, and it would have been
   true of any control any page hides at runtime.
   One rule, at the top of the sheet, so no component below can outrank it. */
/* GAP, BECAUSE INLINE-FLEX EATS THE SPACE (17 Aug). Celina, on the travel board: "this line is a mess
   FLIGHTS 0 HOTELS 0 ALL 0 ...". The markup has always been `FLIGHTS <b>0</b>`, with a real space. But
   putting these components on the rhythm gave them display:inline-flex, and a flex container COLLAPSES
   the whitespace between its children, so every label ran into its own count: FLIGHTS0, HOTELS0, ALL0.
   The fix is the flex-native one: a gap. Not a nbsp, not a margin on the b, because either would have
   to be repeated at every call site that puts two things in a chip.
   THIS IS THE THIRD REGRESSION TODAY FROM THE SAME CAUSE. Giving a component an explicit display is
   never only a sizing change: it also changed what [hidden] could do (22 controls came back) and now
   what whitespace does. Worth writing down: adding display to a shared component changes its LAYOUT
   SEMANTICS, not just its box. */
[hidden]{display:none !important}


/* ════════════════════════════════════════════════════════════════════════════
   SEG : the two-or-three-way toolbar switch
   Source: travel-board.html:83-85 (Fable canonical).
   :disabled added from tour-mgmt.html:76, which carries the same three rules
   plus that state. The two sources are otherwise byte-identical.
   ════════════════════════════════════════════════════════════════════════════ */
/* PHONE SAFETY, measured 27 Aug 2026 by tests/gate_phone_matrix_estate.mjs on WebKit.
   A segmented control is an inline-flex pill that sizes to its content and had NO max-width, so a
   five-button segment reached 504px inside a 375px iPhone SE and pushed the whole PAGE sideways.
   The estate carries three shapes of this same fault (.seg here, .vw on /travel-party, a bare wide
   table on /templates) and they are all one rule: A HORIZONTAL RUN SCROLLS INSIDE ITS OWN BOX, IT
   NEVER SCROLLS THE PAGE. It is unconditional rather than behind a phone breakpoint, because a row
   that outgrows its container is wrong at 1440px too - it only becomes visible on a phone.
   overflow-y stays hidden so the 999px pill clip is unchanged, and the scrollbar is suppressed so
   nothing about the desktop look moves. */
.seg{display:inline-flex;border:1px solid color-mix(in srgb,var(--blue) 34%,transparent);border-radius:999px;overflow-x:auto;overflow-y:hidden;max-width:100%;-webkit-overflow-scrolling:touch;scrollbar-width:none;background:var(--blue-soft)}
.seg::-webkit-scrollbar{display:none}
.seg>*{flex:none}
.seg button{appearance:none;border:none;background:none;color:var(--blue-tx);font-family:inherit;font-weight:800;font-size:11.5px;letter-spacing:.08em;text-transform:uppercase;padding:0 16px;cursor:pointer;height:var(--ctl-h,36px);display:inline-flex;align-items:center;line-height:1}
.seg button.on{background:var(--blue);color:#fff}
.seg button:disabled{color:var(--faint);cursor:default}


/* ════════════════════════════════════════════════════════════════════════════
   CHIP : the filter chip
   Source: tour-mgmt.html:89-96 (Fable canonical). travel-board.html:94-101 is a
   BYTE-IDENTICAL duplicate of the base and deletes on conversion.
   The three status variants are additive and non-conflicting, so all three are
   promoted rather than one page losing its filters:
     .chip.amb   tour-mgmt.html:95-96
     .chip.org   travel-board.html:99-100
     .chip.type  travel-board.html:101-103
   agent-portal.html:59 is NOT this component. It is a count/scope badge that
   was named .chip, and it moves to .badge below.
   ════════════════════════════════════════════════════════════════════════════ */
.chip{border:1px solid var(--line);background:var(--card);border-radius:999px;padding:0 14px;font-size:11.5px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--dim);cursor:pointer;white-space:nowrap;height:var(--ctl-h,36px);display:inline-flex;align-items:center;line-height:1;box-sizing:border-box;gap:6px}
.chip b{color:var(--text)}
.chip:hover{border-color:var(--blue)}
/* NOTE: #fff, not var(--on-blue), is verbatim from both sources. Under the dark
   theme --on-blue is #0b1d33, so tokenising this would repaint every active
   chip from white ink to near-black ink. That is a redraw, not a promotion, so
   it is left alone and carried to the review list instead. */
.chip.on{background:var(--blue);border-color:var(--blue);color:#fff}
.chip.on b{color:#fff}
.chip.amb.on{background:var(--amb-bg);border-color:var(--amb-bd);color:var(--amb-tx)}
.chip.amb.on b{color:var(--amb-tx)}
.chip.org.on{background:var(--org-bg);border-color:var(--org-bd);color:var(--org-tx)}
.chip.org.on b{color:var(--org-tx)}
.chip.type{border-color:color-mix(in srgb,var(--blue) 34%,transparent);color:var(--blue-tx);background:var(--blue-soft)}
.chip.type.on{background:var(--blue);border-color:var(--blue);color:#fff}
.chip.type.on b{color:#fff}
/* the hairline divider between chip groups. tour-mgmt.html:97 == travel-board.html:104 */
.fsep{width:1px;height:20px;background:var(--line);margin:0 4px}


/* ════════════════════════════════════════════════════════════════════════════
   BADGE : a count or a scope, stated. Not clickable, not a filter.
   Source: agent-portal.html:59, RENAMED from .chip to .badge per Fable §5.2
   ("Renamed from .chip to .badge, it is one"). Declarations verbatim; only the
   20px radius conforms to the 999 pill language, which is a no-op at this
   height (the element is 20px tall, so 20px was already a full round).
   MARKUP FOLLOW-UP: agent-portal.html renders class="chip" for these. That
   markup must become class="badge" in the same commit that links this sheet,
   or the badges will pick up the filter-chip rules above.
   ════════════════════════════════════════════════════════════════════════════ */
.badge{font-size:11px;text-transform:uppercase;letter-spacing:.06em;font-weight:700;padding:0 10px;border-radius:999px;background:var(--blue-soft);color:var(--blue-tx);margin-right:6px;height:var(--ctl-h-sm,28px);display:inline-flex;align-items:center;line-height:1;box-sizing:border-box;gap:6px}


/* ════════════════════════════════════════════════════════════════════════════
   PILL : status, stated
   Source: tour-mgmt.html:112-113 (Fable canonical). Four variants retire onto
   it: crew-home.html:112 (unbordered, .14em), crew-tour.html:114,
   travel.html:40 .tourpill, and shell-strip.css .rollon-strip__pill (which
   stays where it is: it lives on the near-black band and is part of the
   chassis, not of this sheet).
   The status modifiers are the estate's status language and are promoted with
   it: .st-* from tour-mgmt.html:114-117 and travel-board.html:133-140. Where
   both files define the same class name they are byte-identical.
   ════════════════════════════════════════════════════════════════════════════ */
/* A PILL IS A READ-OUT, NOT A CONTROL, so it takes the SMALL step and never --ctl-h: a status word
   forced to button height would read as something she can press, which it is not. It still gets the
   optical centring, because it sat 1px high like everything else. */
.pill{font-size:10.5px;font-weight:800;letter-spacing:.05em;text-transform:uppercase;padding:0 10px;border-radius:999px;border:1px solid var(--line);color:var(--pilltx);background:var(--pill);height:var(--ctl-h-sm,28px);display:inline-flex;align-items:center;line-height:1;box-sizing:border-box;gap:6px}
.pill .own{opacity:.72;font-weight:700;margin-left:5px}
/* travel-board.html:132 : the same object under its own name on that board. */
.status{font-size:10.5px;font-weight:800;letter-spacing:.06em;text-transform:uppercase;padding:0 10px;border-radius:999px;border:1px solid var(--line);color:var(--dim);background:var(--card);height:var(--ctl-h-sm,28px);display:inline-flex;align-items:center;line-height:1;box-sizing:border-box;gap:6px}
/* tour-mgmt.html:114-117 */
.st-not_started{color:var(--pilltx);background:var(--pill);border-color:transparent}
.st-initial_sent{color:var(--blue-tx);background:var(--blue-soft);border-color:color-mix(in srgb,var(--blue) 34%,transparent)}
.st-in_progress{color:#fff;background:var(--blue);border-color:var(--blue)}
.st-completed,.st-settled{color:var(--grn-tx);background:var(--grn-bg);border-color:var(--grn-bd)}
/* travel-board.html:133-140 */
.st-posted{color:var(--pilltx);background:var(--pill);border-color:transparent}
.st-orange{color:var(--org-tx);background:var(--org-bg);border-color:var(--org-bd)}
.st-selected{color:var(--blue-tx);background:var(--blue-soft);border-color:color-mix(in srgb,var(--blue) 34%,transparent)}
.st-approved{color:var(--grn-tx);background:var(--grn-bg);border-color:var(--grn-bd)}
.st-set{color:var(--blue-tx);background:transparent;border-color:var(--blue)}
.st-expired{color:var(--amb-tx);background:var(--amb-bg);border-color:var(--amb-bd)}
.st-rejected,.st-withdrawn{color:var(--faint)}
.st-archived{color:var(--faint);background:transparent;border-style:dashed}


/* ════════════════════════════════════════════════════════════════════════════
   BUTTONS
   Primary   : tour-mgmt.html:127 : radius 10, weight 800, uppercase, tracked.
   Ghost     : travel.html:23 (Fable canonical), already tokenised at source.
               NOTE, A REAL CHANGE ON CONVERSION: tour-mgmt.html:128 draws its
               own ghost as background:var(--card);color:var(--blue-tx) with no
               border. Fable names travel.html's as canonical, so on tour-mgmt
               a ghost button becomes transparent on the clay page with a
               hairline, and its ink moves from --blue-tx to --blue. That is
               the promotion Fable ordered, recorded here rather than hidden.
   Disabled  : agent-portal.html:74.
   Secondary : .bbtn, tour-mgmt.html:134 == travel-board.html:160, byte-
               identical duplicates. Both variant sets are promoted because
               they name different actions (.pri/.grn on tour-mgmt,
               .send/.orange/.approve on the travel board) and both boards keep
               working. .bbtn:hover is travel-board-only and is kept.
   ════════════════════════════════════════════════════════════════════════════ */
/* HEIGHT AND OPTICAL CENTRING (17 Aug). Measured across 16 surfaces: 43 distinct control heights,
   and every button in the estate sat 1 to 1.5px HIGH because equal padding does not centre uppercase
   type (a font's ascent and descent are not symmetric about the em box, and caps have no descenders to
   fill the reserved space). height + inline-flex + line-height:1 fixes both at once and holds at any
   size, which a per-control padding nudge does not. */
.btn{border:1px solid var(--blue);background:var(--blue);color:#fff;border-radius:10px;padding:0 18px;font:inherit;font-weight:800;letter-spacing:.05em;text-transform:uppercase;font-size:11.5px;cursor:pointer;height:var(--ctl-h,36px);display:inline-flex;align-items:center;justify-content:center;line-height:1;box-sizing:border-box;gap:6px}
/* travel.html:22, the only hover state any of the six button sets defines.
   Verbatim: background only. The border stays var(--blue) from .btn above,
   because that is what a bordered primary does today on tour-mgmt. */
.btn:hover{background:var(--blue-hi)}
.btn.ghost{background:transparent;color:var(--blue);border:1px solid var(--line)}
.btn:disabled{opacity:.45;cursor:default}
.bbtn{border:1px solid var(--line);background:var(--card);border-radius:9px;padding:0 14px;font:inherit;font-size:12px;font-weight:800;letter-spacing:.04em;text-transform:uppercase;color:var(--text);cursor:pointer;white-space:nowrap;height:var(--ctl-h,36px);display:inline-flex;align-items:center;justify-content:center;line-height:1;box-sizing:border-box;gap:6px}
.bbtn kbd{font:inherit;font-size:10px;opacity:.6;margin-left:5px}
.bbtn:hover{filter:brightness(.97)}
.bbtn.pri,.bbtn.send{background:var(--blue);border-color:var(--blue);color:#fff}
.bbtn.grn,.bbtn.approve{background:var(--grn-bg);border-color:var(--grn-bd);color:var(--grn-tx)}
.bbtn.orange{background:var(--org-bg);border-color:var(--org-bd);color:var(--org-tx)}
/* the floating bulk bar both boards carry. tour-mgmt.html:131-133 == travel-board.html:157-159 */
#bulk{position:fixed;left:50%;bottom:26px;transform:translateX(-50%);display:none;align-items:center;gap:10px;background:var(--card);border:1px solid var(--line);border-radius:14px;padding:10px 14px;box-shadow:var(--bulkshadow);z-index:60}
#bulk.show{display:flex}
#bulk .cnt{font-weight:800;font-size:12.5px;letter-spacing:.04em;text-transform:uppercase;padding:0 6px}


/* ════════════════════════════════════════════════════════════════════════════
   CARD
   Source: agent-portal.html:76 (Fable canonical): --card fill, --line hairline,
   12px, --shadow. max-width:640px is NOT promoted: that is page layout, not the
   component, and agent-portal keeps it on its own wrapper.
   Declared BEFORE .empty on purpose, so class="empty card" (the carded empty
   state, below) keeps the empty state's own padding.
   ════════════════════════════════════════════════════════════════════════════ */
.card{background:var(--card);border:1px solid var(--line);border-radius:12px;padding:18px;box-shadow:var(--shadow)}


/* ════════════════════════════════════════════════════════════════════════════
   EMPTY : one empty state. Six retire.
   Source: travel-board.html:151 (Fable canonical). The carded variant Fable
   also names, crew-tour.html:170, is expressed as class="empty card" rather
   than as a new modifier name, so it composes the card above instead of
   redrawing it. The only difference from crew-tour's own rule is the radius,
   14px there and 12px here, which is the radius language conforming.
   Retiring: tour-mgmt.html:125, agent-portal.html:75, crew-tour.html:170,
   crew-readiness.html:133. grid.html:367 is out of scope until M8.
   ════════════════════════════════════════════════════════════════════════════ */
/* THE EMPTY STATE STACKS ITS ACTION (17 Aug). Celina: "Nothing MATCHES ____CLEAR is so amature too."
   The statement and its action ran together on one line because the action was an inline link. A
   column with a real gap reads as a statement and a way out, which is what an empty state is. */
.empty{padding:60px 22px;text-align:center;color:var(--dim);display:flex;flex-direction:column;align-items:center;gap:14px}
/* tour-mgmt.html:126 : the one-line headline some empties carry above the body */
.empty .big{font-size:15px;font-weight:700;color:var(--text);margin-bottom:6px}


/* ════════════════════════════════════════════════════════════════════════════
   DRAWER / MODAL
   Source: tour-mgmt.html:200-206. rgba(10,8,4,.5) is the scrim and is a
   literal in the source: it is a semantic overlay, not a theme colour, and it
   is identical in #drill (tour-mgmt.html:158) and #sendModal
   (travel-board.html:167), so all three overlays speak one scrim.
   ════════════════════════════════════════════════════════════════════════════ */
.drawer{position:fixed;inset:0;background:rgba(10,8,4,.5);display:none;align-items:center;justify-content:center;z-index:90;padding:26px 20px}
.drawer.show{display:flex}
.drawer .box{background:var(--card);border:1px solid var(--line);border-radius:16px;max-width:680px;width:100%;padding:20px}
.drawer h3{margin:0 0 4px;font-size:16px;font-weight:800}
.drawer .hint{color:var(--dim);font-size:12px;margin-bottom:12px}
.drawer textarea{width:100%;min-height:200px;border:1px solid var(--line);background:var(--page);border-radius:10px;padding:12px;font:12.5px/1.5 ui-monospace,SFMono-Regular,Menlo,monospace;color:var(--text);resize:vertical}
.drawer textarea:focus{outline:none;border-color:var(--blue)}


/* ════════════════════════════════════════════════════════════════════════════
   FIELD-SET VIEW PICKER : the ALL / CONTACT / DIETARY / FLIGHT / IDENTITY switch
   Source: travel.html:36-42 (the 12 Aug ship Celina asked for everywhere).
   .vw/.vb render the segmented control; the .view-<key> rule hides every field
   NOT in the active set with one class on the list root, never per node.
   A field declares its sets with data-fv="fly diet"; a field in no set shows
   only under ALL. assets/field-views.js wires the buttons; this is the paint.
   ════════════════════════════════════════════════════════════════════════════ */
/* Same fault, same rule as .seg above. #artistbar on /travel-party is a .vw holding one button per
   artist, so it grows with the roster: measured 633px inside a 375px phone, 126px past the edge. */
.vw{display:inline-flex;border:1px solid color-mix(in srgb,var(--blue) 34%,transparent);border-radius:999px;overflow-x:auto;overflow-y:hidden;max-width:100%;-webkit-overflow-scrolling:touch;scrollbar-width:none;background:var(--blue-soft)}
.vw::-webkit-scrollbar{display:none}
.vw>*{flex:none}
/* ON THE RHYTHM (17 Aug). Sized by --ctl-h and centred, so it stops sitting a few pixels off
   every control beside it and cannot land on a fractional height. */
.vb{appearance:none;border:0;background:none;color:var(--blue-tx);font:inherit;font-size:10.5px;font-weight:800;letter-spacing:.09em;padding:0 13px;cursor:pointer;height:var(--ctl-h);display:inline-flex;align-items:center;justify-content:center;line-height:1;box-sizing:border-box}
.vb+.vb{border-left:1px solid color-mix(in srgb,var(--blue) 34%,transparent)}
.vb.on{background:var(--blue);color:#fff}
/* when a view is active the list root carries fv-on: a field with data-fv shows only if it names the
   active set. fields with NO data-fv are chrome/always-on and are never hidden. fv-on (not a substring
   match on "view-") so preview-/review-/overview- class names can never trip this rule. */
.fv-on [data-fv]{display:none}
.fv-on.view-contact [data-fv~="contact"],.fv-on.view-diet [data-fv~="diet"],.fv-on.view-fly [data-fv~="fly"],
.fv-on.view-id [data-fv~="id"],.fv-on.view-rights [data-fv~="rights"],.fv-on.view-admin [data-fv~="admin"]{display:block}


/* ════════════════════════════════════════════════════════════════════════════
   HEADINGS : the piece the estate never had, and the reason every page invented
   its own.

   MEASURED 17 Aug by screenshotting 24 surfaces and reading computed styles:
   FOURTEEN different page-heading treatments. Sizes 13/14/15/16/19/20/22/23/26
   /27px, weights 600/660/700/750/800, and TWO not uppercase at all (build.html,
   decide.html), which breaks the UPPER CASE chrome rule outright. There was
   nothing shared to converge ON, so fourteen pages each answered the question
   themselves and all fourteen answers were reasonable.

   PROMOTED, NOT DRAWN. Source: tour-mgmt.html:52 .htitle, the tour-family page
   title, which is also what /advancing and /agent-portal render today and is
   therefore the most-used treatment in the estate. Sized off the token ladder
   rather than the source's literal 12px, because tokens.css owns the scale and
   a component sheet that hardcodes a size reintroduces the drift this file
   exists to end. --fs-head is 15px, which is what those two pages already
   measured at.

   .h-page  the page's name. One per page.
   .h-sec   a section within it, quieter, one step down the same ladder.

   This is added because the specimen page proved the gap: writing /design
   pushed the estate to a FIFTEENTH heading treatment and gate_one_design caught
   it. The honest fix for "there is no shared heading" is a shared heading, not
   a raised baseline.
   ════════════════════════════════════════════════════════════════════════════ */
/* CORRECTED SAME DAY, and the correction matters more than the first version.
   .h-page first mapped to --fs-head, 15px, because that is the MOST-USED heading in the estate. She
   looked at the result and said "This design looks weaker than we had it?" and she was right: most-used
   is not best. 15px is the SECTION step. The pages that read strongest were the ones with a real page
   title (inbox 26px, crew-readiness 27px, ask 27px, decide 23px), and promoting the commonest value
   would have quietened all four to match the smallest. Converging on a lowest common denominator is not
   one design, it is the weakest design that happens to be shared.
   A page's NAME takes the title step. A section within it takes the head step. That is what the ladder
   in tokens.css was built for and nothing on it needed to change. */
.h-page{font-size:var(--fs-title);font-weight:800;letter-spacing:.06em;text-transform:uppercase;color:var(--text);margin:0;line-height:1.15}
.h-sec{font-size:var(--fs-head);font-weight:800;letter-spacing:.10em;text-transform:uppercase;color:var(--text);margin:0}
.h-sub{font-size:var(--fs-section);font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--dim);margin:0}


/* ═══════════════════════════════════════════════════════════════════════════════════════════════
 * THE PHONE FLOOR, ON THE SHARED COMPONENTS. HERS, 27 Aug 2026: 12px text and 44px targets below
 * 719px, with the desktop deliberately left dense.
 *
 * THE PILL IS THE ESTATE'S MOST REUSED PIECE. It reads at 10.5px, and it is how a tour day says
 * "Travel", an invoice says "PAID" and a person says "Writer". It surfaced on /tour first and the
 * temptation was to fix it there; it is on nearly every surface, so it comes up HERE once.
 * That is the same rule the 25-surface nav fix followed a few hours earlier.
 * ═══════════════════════════════════════════════════════════════════════════════════════════════ */
@media (max-width: 719px), (pointer: coarse) and (max-height: 500px) {
  .pill { font-size: 12px; }
}
