@layer utilities {
/* static/css/mobile.css — shared portrait/small-screen rules.
 *
 * Loaded by the admin panel, the provider portal and the public base template.
 * Shell-specific mobile behaviour (the admin sidebar drawer, the tab overlay)
 * stays inline in templates/admin/base.html — this file is only the rules that
 * are identical everywhere.
 *
 * Breakpoint is Bootstrap's md (767.98px) so it lines up with col-md-*.
 */

@media (max-width: 767.98px) {
    /* THE PAGE FRAME ON A PHONE (tokens.css owns the desktop values). A desk
       gutter on a 390px screen spends a fifth of the width on air and pushes
       the first row below the 140px chrome budget; 2px, which `.page-shell`
       used before this, put cards against the glass. One small step each. */
    :root {
        --page-inset-block:  var(--space-2);
        --page-inset-inline: var(--space-3);
        --page-gap:          var(--gap-group);
    }

    /* ── Release the desktop viewport lock ────────────────────────────────
       All three shells (admin, provider, HHN portal) pin the page to the
       viewport — `height: 100%/100vh` with `overflow: hidden` — and delegate
       scrolling to an inner container. That is a desktop layout. On a phone it
       cuts off the bottom of every page (100vh excludes the browser chrome) and
       stops the URL bar auto-hiding on scroll.

       Below md the page scrolls normally instead. The admin shell also declares
       this in its own block; repeating it here is deliberate so the HHN portal —
       a standalone document with no base template — gets it too. */
    html, body {
        height: auto !important;
        min-height: 100%;
        overflow: visible !important;
    }

    /* ── Tables ───────────────────────────────────────────────────────────
       Default treatment is a SCROLL CONTAINER, not a card transform. NN/g's
       eye-tracking work on data tables finds a card presentation "requires
       users to spatially reorient each time they move their eyes from one card
       to another, making comparison tasks cognitively effortful and slow" —
       and comparison, outlier-scanning and sorting are what this app's users
       actually do. W3C SC 1.4.10 exempts data tables from reflow for the same
       reason: the two-dimensional relationship carries meaning.

       So wide tables scroll, inside a focusable labelled region, and only the
       tables whose ROWS ARE ENTITIES YOU OPEN become `.rowcard` (below).
       See plans/ui-revamp/RESEARCH-RESULTS-tables.md §1 and §3. */
    .rt-scroll {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
    /* Scroll must be DISCOVERABLE. A table sliced mid-column with no cue reads
       as broken, not as "there is more this way" — which is the complaint that
       every reachability check passes while the user still sees a defect.
       W3C exempts data tables from reflow, so scrolling is correct; NN/g's
       caveat is that it only works if the user can see that it scrolls.

       Komarov's scrolling-shadows technique: the two white gradients are
       `background-attachment: local` so they ride WITH the content and cover
       the shadow when you are at that end; the two radial shadows are `scroll`
       so they stay pinned to the edges. Net effect — a shadow appears only on
       the side that has content off-screen. Pure CSS, no JS, no scroll
       listener to keep in sync. */
    .rt-scroll,
    .table-responsive {
        background: var(--scroll-cue-background);
        background-repeat: no-repeat;
        background-size: 36px 100%, 36px 100%, 12px 100%, 12px 100%;
        background-attachment: local, local, scroll, scroll;
    }
    .rt-scroll:focus-visible {
        outline: 2px solid var(--status-primary);
        outline-offset: 2px;
    }
    /* Scrolling must be discoverable: a table cut off with no cue reads as a
       broken layout rather than as more content. */
    .rt-scroll { scrollbar-width: thin; }

    /* ── .rowcard — the CPO/CCM entry row, generalised ─────────────────────
       Cells declare a ROLE; the card composes them. The generic
       `data-label` + `::before` stack — "ADDRESS 5500 Oakton St" on its own
       line, once per column — is what the research offers cheaply and it reads
       like a form dump. CPO/CCM does not label its lines, it composes them:

           Abigail Osei                         143
           5500 Oakton St                       min
           Dr. Smith · Demo Home Health C

       Roles, applied to the <th> (DataTables copies them to every <td>) or to
       the cells directly:

         .card-title   identity — full width, carries the weight, opens the record
         .card-line    the one secondary fact worth a line of its own
         .card-meta    attribution — several of these sit on ONE line, joined by ·
         .card-value   the number that matters, pinned right in a fixed column

       A cell with no role is HIDDEN. That makes "would a phone user act on
       this?" an explicit decision per column rather than something that happens
       by default — the opposite of stacking all eight and hoping. */
    table.rowcard,
    table.rowcard thead,
    table.rowcard tbody,
    table.rowcard tr,
    table.rowcard td { display: block; width: 100%; }
    table.rowcard thead { display: none; }
    table.rowcard tr {
        display: flex; flex-wrap: wrap; align-items: baseline;
        gap: 2px var(--space-2);
        padding: var(--space-3) var(--space-2);
        border-bottom: 1px solid var(--border);
        min-height: var(--control-height);
    }
    /* Unroled cells are cut, not stacked.
       `background: transparent` is load-bearing: Bootstrap paints every cell
       (`.table > :not(caption) > * > *` sets `--bs-table-bg`) while DataTables
       tints the ROW, so opaque cells sat on a tinted row and every text block
       came out with its own visible grey box. A card is one surface. */
    table.rowcard td {
        display: none; width: auto; border: none; padding: 0;
        background: transparent !important;
        /* DataTables 2.x paints stripe/hover/sorted-column with an INSET
           BOX-SHADOW (`inset 0 0 0 9999px rgba(0,0,0,.02)`) on the CELL, not a
           background — deliberately, so it composites over row colours. So
           `background: transparent` alone left every value sitting in its own
           grey box while computed `backgroundColor` read as transparent on all
           375 elements. Both properties have to go. */
        box-shadow: none !important;
    }
    /* `.rowcard` + `.table-dense` on the same table, which is the combination
       PAGE-STANDARD §2 actually asks for: dense grid on desktop, card on a
       phone. It did not work, and the reason is pure specificity.

       `.table-dense > tbody > tr > td` is (0,1,3); `table.rowcard td` above is
       (0,1,2). So the DESKTOP rule won inside the mobile media query and every
       cell kept `height: var(--tbl-row-h)`, its cell padding and its own
       bottom border — a card whose parts were each boxed and 34px tall. It
       looked like the transform had not loaded at all.

       Matching (0,1,3) and relying on mobile.css loading after tables.css is
       enough; `!important` is not needed and would be harder to override on a
       page that legitimately needs to. Nothing used `.rowcard` before the
       provider portal, which is why this never surfaced. */
    table.rowcard > tbody > tr > td {
        height: auto;
        padding: 0;
        border: none;
        vertical-align: baseline;
    }

    /* Zebra off in card mode — the border already separates cards, and a stripe
       under a three-line card reads as a highlight rather than a row. */
    table.rowcard tbody tr,
    table.rowcard tbody tr.odd,
    table.rowcard tbody tr.even { background: transparent !important; }
    table.rowcard tbody tr:hover { background: var(--surface-sunken) !important; }

    table.rowcard td.card-title {
        /* Shares line one with the value: `flex: 0 0 100%` forced the value to
           wrap onto its own row ABOVE the name, which read as a floating date. */
        display: block; flex: 1 1 auto; min-width: 0;
        order: 0;
        font-size: var(--fs-md); font-weight: var(--fw-medium); color: var(--text);
        overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    }
    /* Line one is `title … value` and ENDS there. Without this the break was
       decided by how long the patient's name happened to be: flex breaks lines
       on content width, and `margin-left: auto` on the value is applied AFTER
       lines are formed, so short names left room and the metas rode up onto
       line one — "Nolan, Dominic  07/28/2026  DEMO-0216  01/21/1934" — while
       long names pushed them down. Same markup, two layouts, decided by data.

       A zero-height full-width flex item is the only thing that forces a break
       at a chosen point. Its `order` sits between the value (1) and everything
       below (3, 4), which is why those two were renumbered. */
    table.rowcard tr::after {
        content: ''; flex: 0 0 100%; height: 0; order: 2;
    }
    table.rowcard td.card-line {
        display: block; flex: 0 0 100%; order: 3;
        font-size: var(--fs-sm); color: var(--text-muted);
        overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    }
    /* Several metas share one line, separated the way prose would separate
       them — not stacked with a label each. */
    table.rowcard td.card-meta {
        display: inline-block; flex: 0 0 auto; order: 4;
        font-size: var(--fs-2xs); color: var(--text-subtle);
    }
    /* Separator BEFORE each meta after the first. `:last-of-type` counts every
       <td> in the row — including the hidden ones — so it left a trailing `·`
       on the last visible meta. A sibling combinator only sees the class. */
    table.rowcard td.card-meta ~ td.card-meta::before {
        content: '· '; color: var(--text-subtle);
    }
    /* The number, in a fixed column so values align down the list. */
    /* Explicit order, because DOM order is column order and the value is rarely
       column two. Line one is title + value; everything else wraps beneath. */
    table.rowcard td.card-value {
        display: block; flex: 0 0 auto; order: 1; margin-left: auto;
        text-align: right; white-space: nowrap;
        font-size: var(--fs-md); color: var(--text);
        font-variant-numeric: tabular-nums;
    }
    /* One link colour per card, on the identity. The server renders most cells
       as anchors, so a card came out with four blue values and nothing read as
       more clickable than anything else — colour means "click here" only while
       it is rare. Everything except the title inherits its cell's colour; the
       whole row is the tap target anyway. */
    table.rowcard td a { color: inherit; text-decoration: none; }
    table.rowcard td.card-title a { color: var(--status-primary); }

    /* `.cell-truncate` sets `max-width: 0` — the idiom that makes a cell
       truncate under the AUTO TABLE layout algorithm, where 0 is read as "as
       narrow as possible" and the column then takes its share. A `.rowcard` row
       is `display: flex`, where `max-width: 0` means exactly what it says, so
       the patient's name rendered at zero width and the card showed a bare
       "45 min" with no idea who it belonged to.
       The card roles already truncate (nowrap + ellipsis), so the table idiom is
       simply switched off here rather than fought. */
    table.rowcard td.cell-truncate { max-width: none; }

    /* Labels belong to the generic stack, not to a composed card. */
    table.rowcard td[data-label]::before { content: none !important; }
    table.rowcard td:empty { display: none; }

    /* ── Outer gutters ────────────────────────────────────────────────────
       Two nested containers each add horizontal padding before a page's own
       components add theirs: `.container-fluid` 9px + `.main-content` 12px, so
       a list row starting with 12px of its own padding began 33px from the edge
       — 42px of a 390px screen spent on margin, twice.

       The outer two go to zero and components keep their own padding, which is
       the phone convention (full-bleed surfaces, padded content) and gives the
       width back to the data. Desktop is untouched. */
    .container-fluid,
    .main-content,
    /* Bootstrap sizes every grid child with `.row > *` (specificity 0,1,1), which
       outranks a bare `.main-content` and was the rule actually setting the 12px.
       Matching its shape is what beats it. */
    .row > .main-content,
    .row > .col-12 {
        padding-left: 0 !important;
        padding-right: 0 !important;
    }
    /* The framed case is handled at the shell (admin/base.html,
       `html.in-iframe .main-content-wrapper`) because it applies at every width,
       not just here. Its rule is (0,2,1) with !important, which is why nothing
       targeting `.main-content` alone could reach it. */
    /* Bootstrap's grid is a MATCHED PAIR: `.container-*` adds horizontal padding
       and `.row` cancels it with an equal negative margin, so the first and last
       columns sit flush with the container's content box. Zeroing the padding
       above without zeroing the margin left every `.row` hanging half a gutter
       past the viewport — which is exactly why nine pages drifted by a uniform
       6px or 9px (the two gutter values in use).

       Columns keep their own padding, so content is still inset from the screen
       edge; what is gone is the container's outer band, which is the point. */
    .row {
        margin-left: 0 !important;
        margin-right: 0 !important;
    }

    /* Prose pages have no component padding of their own, so they keep a gutter. */
    .main-content > .alert,
    .main-content > .card,
    .main-content > p,
    .main-content > h1, .main-content > h2, .main-content > h3,
    .main-content > h4, .main-content > h5, .main-content > h6 {
        margin-left: var(--space-2);
        margin-right: var(--space-2);
    }

    /* ── Touch targets ────────────────────────────────────────────────────
       The 12px root leaves controls around 30px tall, under the ~44px needed for
       a reliable finger target, so floor the interactive controls.

       Deliberately NOT bumping the root font-size. That was tried and reverted:
       73 form controls across 31 templates carry hardcoded pixel widths
       (`style="width: 180px"`) calibrated against the 12px root. Scaling type by
       ~17% overflows those fixed widths and makes Bootstrap input-groups wrap
       into a broken staircase — the toolbar on the Timetable page was the
       clearest case. Type scale has to wait until those widths are tokenised. */
    /* THE CONTROL FLOOR IS NOT HERE — it keys on POINTER, in tokens.css.
       This block used to floor `.btn`/`.form-control`/`.form-select` to
       `var(--touch-target)` by WIDTH, which is the wrong condition and the note
       directly above already said so ("a touch device is a touch device at any
       viewport width"). tokens.css line ~283 already applies
       `min-height: var(--control-height)` under `@media (any-pointer: coarse)`,
       so this was the duplicate that note warns about — two rules setting one
       property.

       What the duplicate actually did: browser zoom shrinks the CSS-px viewport,
       so zooming a DESKTOP past ~190% drops it under 768px and fired a finger
       floor at a mouse. MEASURED on the HDForms fill surface, no touch device:
       input min-height 34px at 100-175% zoom, then 44px from ~190% on, with the
       text still 16px — the box inflating around unchanged text. That is what
       "if i zoom in too much, the textbox gets too big" was.

       Real phones are unaffected: they match `any-pointer: coarse` at every zoom
       level, so the 44px target comes from tokens.css exactly as before. */

    /* THE 32px ROW-BUTTON FLOOR IS GONE, and it must not come back here.
       `.table .btn, .btn-group-sm > .btn { min-height: 32px }` used to sit at
       this point. Both selectors outrank the (0,1,0) floor in tokens.css, and
       this sheet loads last, so it won: every table row action and every
       segmented control measured 32px under a finger. The visual harness
       measured the pair on /admin/patients and /provider/patients — the Card
       and Table buttons, 32.0px tall at 390px with a coarse pointer — while
       tokens.css already named `.table .btn` and `.btn-group-sm > .btn` in its
       own floor list at var(--touch-target).

       tokens.css floors them at 44px now, and it is the only rule that does.
       Do NOT re-add a control height here, and do NOT key one on viewport
       width: the block above records what that costs. Browser zoom shrinks the
       CSS-px viewport, so a width-keyed floor fires a finger target at a
       zoomed desktop mouse. The floor keys on pointer. */

    /* NOTE: control font-size (the iOS zoom fix), control heights and the
       standalone-action-link floor are NOT here. They live in tokens.css under
       `@media (any-pointer: coarse)`, which is the better condition — a touch
       device is a touch device at any viewport width. Adding a second copy here
       was tried during the mobile audit and reverted: two rules setting the same
       property is exactly what `check_shared_components.py` exists to stop, and
       the duplicate silently lost to Bootstrap's `.form-select-sm` anyway. */

    /* ── Overflow ─────────────────────────────────────────────────────────
       Wide content scrolls inside its own container instead of pushing the
       page sideways. */
    .table-responsive {
        overflow-x: auto !important;
        -webkit-overflow-scrolling: touch;
    }

    /* Long pagination (20+ numbered links) overflows a phone. */
    .pagination {
        flex-wrap: wrap;
        row-gap: var(--space-1);
    }

    /* Page toolbars are written as one non-wrapping flex row of fixed-width
       controls (a 180px period picker + a 110px select + an action button is a
       common shape). That comfortably exceeds a 375px phone, so the row overflows
       and the action button falls off screen. Let these rows wrap instead.
       .flex-nowrap opts a row out where wrapping would be wrong. */
    /* Both shapes occur: a flex row *inside* a card section, and a card section
       that is itself the flex row (`<div class="card-header d-flex …">`). */
    .card-body > .d-flex:not(.flex-nowrap),
    .card-header > .d-flex:not(.flex-nowrap),
    .card-body.d-flex:not(.flex-nowrap),
    .card-header.d-flex:not(.flex-nowrap) {
        flex-wrap: wrap;
        row-gap: var(--space-2);
    }

    /* Toolbars also appear as a bare `d-flex` outside any card — a row of
       selects plus an action button. Those were not covered by the card-scoped
       rules above, and they overflow as soon as controls grow to touch size.
       :has() targets "a flex row that actually contains controls", so ordinary
       layout flex rows are untouched. .flex-nowrap opts a row out. */
    .d-flex:not(.flex-nowrap):has(> .form-select),
    .d-flex:not(.flex-nowrap):has(> .form-control),
    .d-flex:not(.flex-nowrap):has(> .btn) {
        flex-wrap: wrap;
        row-gap: var(--space-2);
    }

    /* Form controls carrying an inline pixel width inside a flex row must be able
       to shrink. A single `style="width: 320px"` search box already exceeds a
       390px viewport, and flex items do not shrink below their specified width,
       so the row pushes the page sideways.

       Targeting the style attribute is deliberate: 73 controls across 31 templates
       carry these widths and CSS cannot match them by value any other way. Width
       is released rather than forced to 100% so the control still shares the row
       with its siblings instead of stacking them. */
    .d-flex > .form-control[style*="width"],
    .d-flex > .form-select[style*="width"],
    .d-flex > .input-group[style*="width"],
    .d-flex > * > .form-control[style*="width"] {
        width: auto !important;
        flex: 1 1 auto;
        min-width: 0;
    }

    /* ── Split layouts ────────────────────────────────────────────────────
       ~208 columns across the app are written as bare `col-6` / `col-8` rather
       than `col-md-6`. Bare col-N applies at every breakpoint, so a two-pane
       page stays two panes on a 375px phone — roughly 180px per pane, which is
       where the unreadable "left and right side" pages come from.

       The :not() chain is the important part: it matches only columns whose
       author never specified responsive behaviour. An element written as
       `col-6 col-md-4` is a deliberate "half width on mobile" choice and is left
       alone. Narrow columns (col-1..col-3) are chips and labels that read fine
       side by side, so only a third-width and wider is stacked.

       The :not() tests deliberately omit the trailing hyphen. Bootstrap's
       auto-width column is bare `col-md` (no number), so `col-6 col-md` — the
       standard "two-up on phones, equal widths on desktop" idiom used by every
       stat tile row in the analytics pages — does NOT contain the substring
       "col-md-". Matching on "col-md-" therefore treated those as
       non-responsive and forced them full width, turning a tidy 2×3 stat grid
       into six full-width tiles. Match on "col-md" so both forms are excluded. */
    .row > .col-4:not([class*="col-sm"]):not([class*="col-md"]):not([class*="col-lg"]):not([class*="col-xl"]),
    .row > .col-6:not([class*="col-sm"]):not([class*="col-md"]):not([class*="col-lg"]):not([class*="col-xl"]),
    .row > .col-8:not([class*="col-sm"]):not([class*="col-md"]):not([class*="col-lg"]):not([class*="col-xl"]),
    .row > .col-9:not([class*="col-sm"]):not([class*="col-md"]):not([class*="col-lg"]):not([class*="col-xl"]),
    .row > .col-10:not([class*="col-sm"]):not([class*="col-md"]):not([class*="col-lg"]):not([class*="col-xl"]),
    .row > .col-11:not([class*="col-sm"]):not([class*="col-md"]):not([class*="col-lg"]):not([class*="col-xl"]) {
        flex: 0 0 100%;
        max-width: 100%;
    }

    /* ── Tab bars ─────────────────────────────────────────────────────────
       Bootstrap nav-tabs wrap, so a 7-tab bar (the patient chart) becomes three
       stacked rows of tabs that push the content down and read as a menu rather
       than tabs. Scroll horizontally instead — the shape stays recognisable. */
    .nav-tabs {
        flex-wrap: nowrap;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
    }
    .nav-tabs::-webkit-scrollbar {
        display: none;
    }
    .nav-tabs .nav-link {
        white-space: nowrap;
    }

    /* Same treatment for a tab strip built as a plain flex row rather than with
       Bootstrap's `.nav-tabs` — `role="tablist"` is the reliable signal, and it
       is what the Stedi island's `.sx-views` uses.

       This surfaced when the control font-size went to 16px on touch (the iOS
       zoom fix in tokens.css): every tab label grew, the strip went 21px past
       the viewport, and because it had no scroll of its own that 21px became
       page overflow. `overflow-x: auto` keeps it inside the strip. `min-width: 0`
       is required for the same reason as everywhere else — without it the strip
       refuses to shrink below its content and has nothing to scroll.

       The pill strip (`.sel-strip-pill`, selection.css) is the one exception:
       it has no frame, so it wraps on a phone instead of scrolling. */
    [role="tablist"]:not(.sel-strip-pill) {
        flex-wrap: nowrap;
        min-width: 0;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
    }
    [role="tablist"]::-webkit-scrollbar {
        display: none;
    }
    [role="tablist"] > * {
        flex: 0 0 auto;
        white-space: nowrap;
    }

    /* ── Master–detail pattern ────────────────────────────────────────────
       For the bespoke "workflow" pages built as desktop app shells: a fixed-width
       list pane beside a detail pane (cpo_ccm_time, billing_workflow, signing
       queue, …). Squeezing both onto a phone gives a 260px list next to a ~115px
       detail — the list reads as a huge empty margin and the real content is
       unusable.

       On small screens the panes become one-at-a-time: the list fills the screen
       until something is selected, then the detail replaces it, with a back
       button to return. This is how native apps handle the same layout.

       To adopt on a page:
         1. add .mobile-master-detail to the flex row
         2. add .md-list  to the list pane
         3. add .md-detail to the detail pane
         4. toggle .md-detail-open on the row when a row is selected/cleared
         5. add a .md-back button inside the detail header
       Desktop layout is untouched — every rule here is inside the media query. */
    .mobile-master-detail {
        flex-direction: column !important;
    }
    .mobile-master-detail > .md-list {
        width: 100% !important;
        min-width: 0 !important;
        flex: 1 1 auto !important;
        /* The vertical twin, and the one this pattern was missing: a flex child
           defaults to `min-height: auto` and refuses to shrink below its
           content, so a pane told to fill the screen instead GREW to its list's
           full height — and anything inside it with `overflow: auto` then had
           nothing to scroll. Traced on /provider/activity: the pane was 3,601px
           inside an 844px screen. */
        min-height: 0 !important;
        border-right: none !important;
    }
    .mobile-master-detail.md-detail-open > .md-detail {
        min-height: 0 !important;
    }
    .mobile-master-detail > .md-detail {
        display: none !important;
    }
    .mobile-master-detail.md-detail-open > .md-list {
        display: none !important;
    }
    .mobile-master-detail.md-detail-open > .md-detail {
        display: flex !important;
        width: 100% !important;
        flex: 1 1 auto !important;
    }
    .md-back {
        /* Needs the flex alignment spelled out: .btn is inline-block by default,
           so switching to inline-flex without these leaves the icon and label
           laid out as separate lines, which renders as a chevron floating
           outside the button box. */
        display: inline-flex !important;
        align-items: center;
        justify-content: center;
        white-space: nowrap;
        width: auto;
        /* A chevron-only button has almost no intrinsic width, and `.page-actions` is a
           flex row — so in a header with a long title it shrank to 16px wide against a
           44px height. MEASURED on /admin/signing-queue: 16x44. It is the only way back
           to the list on a phone, so it does not get to be the thing that shrinks. */
        min-width: var(--touch-target);
        flex: 0 0 auto;
    }
}

@media (max-width: 767.98px) {
    .main-content { padding: 0.75rem !important; }
    .d-mobile-none { display: none !important; }
}

@media (min-width: 768px) {
    .app-drawer-backdrop { display: none !important; }
}

/* The back control belongs to the mobile pattern only — hidden by default so it
   never appears on desktop. Outside the media query on purpose. */
.md-back {
    display: none;
}

@media (max-width: 767.98px) {
    /* ── Smaller text and padding on mobile ────────────────────────────────
       Moved from templates/admin/base.html — identical everywhere this file
       is loaded (admin, provider, the public base template), so it belongs
       here rather than reaching into shared components from one shell's
       inline <style> (scripts/check_bare_bootstrap.py). */
    .card-body { padding: 0.75rem; }
    .btn { font-size: 0.85rem; }
    .btn-sm { font-size: 0.75rem; padding: 0.2rem 0.4rem; }
    .table { font-size: 0.8rem; }
}
}
