/* ═══════════════════════════════════════════════════════════════
   careiti-tablet.css — 平板（iPad）長者版面層
   Loaded last on every page that opts in with <body data-ct="app">.

   The thesis, and the reason this file is small:

     A tablet in an elder's hands is a MAGNIFIER, not a desktop.

   The app was authored at a fixed phone width (480–560px columns of
   9–13px text). Rendered on an iPad that leaves 40–60% of the screen
   empty while the type stays too small to read — the worst of both.
   The fix is therefore NOT to pour more content into the width. It is
   to spend the extra pixels making the same content bigger: one column,
   larger type, larger targets, more air.

   ── How the scale works ────────────────────────────────────────
   Every px font-size in the opted-in pages is authored as
       font-size: max(calc(13px * var(--ct-k2,1)), var(--ct-min,0px))
   so a handful of variables drive the whole app. Three consequences:

     1. Tablet scaling is five numbers per breakpoint, not 959 overrides.
     2. 大字模式 finally works. It used to set html{font-size:118%},
        which does nothing on pages that pin every size in px — seniors
        pressed the button and the page did not change. It now feeds
        --ct-lf into the same calc, so it scales everything.
     3. The ramp is non-linear, which is the whole point (see below).

   ── Why the ramp is non-linear ─────────────────────────────────
   The obvious design is one multiplier for everything. It fails the
   audience: 9px text scaled by 1.16 is 10.4px, so the type that was
   already unreadable stays unreadable while the headings get roomy.
   Elders need a FLOOR, not a ratio.

   So each size sits in a bucket, and smaller buckets are scaled harder.
   Source sizes spanning 9–22px (2.4x) land at 16–28px (1.75x) on a 12.9"
   iPad: the order survives, the range compresses, and the bottom of the
   range clears readability. Compressing size hierarchy costs little here
   because MASTER.md already specifies that hierarchy comes from position,
   weight, rule lines and whitespace rather than from size.

   --ct-min is the backstop: whatever the buckets work out to, no text on
   a tablet renders below it.

   The `,1` and `,0px` fallbacks mean that if this sheet fails to load the
   app renders at its original phone sizing rather than breaking. At phone
   width with 大字模式 off every multiplier is 1 and --ct-min is 0, so the
   computed styles are identical to before this file existed — an
   invariant verified by a computed-style fingerprint diff over ~4000
   elements, not by eye.
   ═══════════════════════════════════════════════════════════════ */

:root {
  /* Per-bucket breakpoint scales. Smaller type is scaled harder. */
  --ct-s1: 1;      /* ≤11px — micro labels, captions, nav labels */
  --ct-s2: 1;      /* 12–13px — secondary text, the app's commonest size */
  --ct-s3: 1;      /* 14–17px — body */
  --ct-s4: 1;      /* 18–24px — subheads */
  --ct-sd: 1;      /* >24px — display numerals, already large */

  --ct-lf: 1;      /* 大字模式 multiplier, applied to every bucket */

  --ct-k1: calc(var(--ct-s1) * var(--ct-lf));
  --ct-k2: calc(var(--ct-s2) * var(--ct-lf));
  --ct-k3: calc(var(--ct-s3) * var(--ct-lf));
  --ct-k4: calc(var(--ct-s4) * var(--ct-lf));
  --ct-kd: calc(var(--ct-sd) * var(--ct-lf));

  --ct-min: 0px;               /* absolute font-size floor */
  --ct-tap: 44px;              /* tap target floor */
  --ct-gut: 16px;              /* page gutter */
  --ct-pad: 1;                 /* card padding multiplier */
  --ct-max: 100%;              /* content column ceiling */
}

/* 大字模式 — the app has two toggles and they do not agree on where the
   class goes: careiti-a11y.js stamps <html> AND <body>, b4d-theme-toggle.js
   (the per-page "A" button) stamps <body> only.
   That difference is fatal to the obvious version of this rule. The --ct-k*
   variables below are DERIVED, and a derived custom property is substituted
   at computed-value time on the element that declares it — here, :root. A
   descendant inheriting --ct-k1 inherits the already-resolved token stream
   `calc(1.60 * 1)`; setting --ct-lf further down the tree cannot reach back
   and re-run that calc. So with the class on <body> only, every calc()-sized
   piece of text in the app — which is nearly all of it — did not move, and
   pressing the button appeared to do nothing.
   The fix is to re-derive the whole set wherever the class lands, so the
   variables are recomputed on that element and inherit down correctly. The
   --ct-s* inputs are plain numbers and inherit cleanly, so this reads the
   right breakpoint values at either level.
   (b4d-theme-toggle.js is also being made to stamp <html> like the other
   toggle does. Both halves are kept: the JS fix makes the two toggles
   consistent, this makes the stylesheet correct no matter which element a
   future caller decides to mark.) */
html.large-font, body.large-font {
  --ct-lf: 1.18;
  --ct-k1: calc(var(--ct-s1) * 1.18);
  --ct-k2: calc(var(--ct-s2) * 1.18);
  --ct-k3: calc(var(--ct-s3) * 1.18);
  --ct-k4: calc(var(--ct-s4) * 1.18);
  --ct-kd: calc(var(--ct-sd) * 1.18);
}

/* ── Breakpoints ──────────────────────────────────────────────
   700px catches the narrowest iPad in portrait (mini, 744px CSS).
   1000px catches iPad Pro 12.9 portrait (1024) and every landscape iPad. */

/* iPad mini / 10.9" / Air in portrait.
   10px → 16px, 13px → 18.2px, 16px → 20.8px, 22px → 26.4px, 42px → 45.4px */
@media (min-width: 700px) {
  :root {
    --ct-s1: 1.60;
    --ct-s2: 1.40;
    --ct-s3: 1.30;
    --ct-s4: 1.20;
    --ct-sd: 1.08;
    --ct-min: 15px;
    --ct-tap: 56px;
    --ct-gut: 28px;
    --ct-pad: 1.35;
    --ct-max: 700px;
  }
}

/* iPad Pro 12.9" portrait and every landscape iPad wide enough for it.
   10px → 17.8px, 13px → 20.2px, 16px → 22.7px, 22px → 28.2px, 42px → 48.3px */
@media (min-width: 1000px) {
  :root {
    --ct-s1: 1.78;
    --ct-s2: 1.55;
    --ct-s3: 1.42;
    --ct-s4: 1.28;
    --ct-sd: 1.15;
    --ct-min: 16px;
    --ct-tap: 60px;
    --ct-gut: 36px;
    --ct-pad: 1.6;
    --ct-max: 820px;
  }
}

/* Short landscape (iPad Pro 11 at 1194×834, mini at 1133×744): vertical
   space is the scarce resource, not horizontal. Back the type ramp off so
   a question and its answers still fit without scrolling — losing the
   question off the top of the screen mid-answer is far more disorienting
   for an elder than slightly smaller type. */
@media (min-width: 700px) and (max-height: 900px) and (orientation: landscape) {
  :root {
    --ct-s1: 1.50;
    --ct-s2: 1.32;
    --ct-s3: 1.22;
    --ct-s4: 1.12;
    --ct-sd: 1.0;
    --ct-min: 15px;   /* the floor does not move: the screen got shorter,
                         the reader did not get younger */
    --ct-tap: 52px;
    --ct-gut: 28px;
    --ct-pad: 1.15;
  }
}

/* Known limitation, recorded deliberately: ~60 declarations across the app
   size in rem rather than px and so ride the root font-size, not --ct-k.
   Scaling the root here would take precedence over html[data-skin="senior"]
   (108%) and html.large-font (118%) and silently disable both — a worse
   outcome for this audience than leaving a small tail unscaled. Those
   declarations are mostly input sizing in careiti-skin.css, which the tap
   target rules below already give a tablet-sized hit box. */

/* ═══════════════════════════════════════════════════════════════
   Everything below is scoped to body[data-ct="app"] so pages with their
   own layout contract — the marketing site, the admin console, the B2B
   portal — are untouched. The two-class scope also outranks the
   single-class rules in each page's inline <style>, so this file needs
   !important in exactly one place: the landscape gameplay grid, which has
   to beat a display value the games write inline from JS. That one case is
   argued where it appears.
   ═══════════════════════════════════════════════════════════════ */

/* ── Content column ───────────────────────────────────────────
   Widen the phone column, but only to a comfortable reading measure.
   At --ct-max 820px with body text scaled to ~22px that is roughly 34
   CJK characters per line — inside the comfortable 25–40 range. Going
   full-bleed would be easy and wrong. */
@media (min-width: 700px) {
  body[data-ct="app"] .container,
  body[data-ct="app"] .page,
  body[data-ct="app"] .wrap,
  body[data-ct="app"] .play-wrap,
  body[data-ct="app"] .result-wrap,
  body[data-ct="app"] .records-wrap,
  body[data-ct="app"] .tabs-wrap,
  body[data-ct="app"] .dash-wrap,
  body[data-ct="app"] .home-content,
  body[data-ct="app"] .login-box,
  body[data-ct="app"] .c-wrap {
    max-width: var(--ct-max);
    padding-left: var(--ct-gut);
    padding-right: var(--ct-gut);
    /* Load-bearing. `.page` means two different things in this codebase: on
       the quiz games it is the content column and already carries
       `margin:0 auto`; on /my and /history it is a full-height flex shell
       with `margin:0`. Clamping the second kind without this pinned an
       820px box to the left edge and left ~370px of bare paper down the
       right of the screen — the "側埋左一邊無置中" report. Auto inline
       margins centre both kinds, and neither carries its own background
       (the paper comes from body), so there is no banding to worry about. */
    margin-inline: auto;
  }

  /* Cards that were centred at a fixed narrow width follow the column. */
  body[data-ct="app"] .card,
  body[data-ct="app"] .modal-sheet,
  body[data-ct="app"] .modal-box {
    max-width: var(--ct-max);
  }
}

/* ── Vertical rhythm ──────────────────────────────────────────
   Padding grows with the type, otherwise scaled text sits in cramped
   boxes that were measured for 13px. */
@media (min-width: 700px) {
  body[data-ct="app"] .card,
  body[data-ct="app"] .c-card,
  body[data-ct="app"] .q-card,
  body[data-ct="app"] .result-card,
  body[data-ct="app"] .level-card,
  body[data-ct="app"] .lv-card,
  body[data-ct="app"] .reward-card,
  body[data-ct="app"] .sub-card {
    padding: calc(16px * var(--ct-pad)) calc(18px * var(--ct-pad));
    border-radius: calc(16px * var(--ct-pad));
  }

  body[data-ct="app"] .hero {
    padding: calc(32px * var(--ct-pad)) var(--ct-gut) calc(40px * var(--ct-pad));
  }
}

/* ── Tap targets ──────────────────────────────────────────────
   44px is the WCAG floor for a phone held close. An elder on a tablet
   held at arm's length, often with a tremor, gets 56–60px. */
@media (min-width: 700px) {
  body[data-ct="app"] button,
  body[data-ct="app"] .btn,
  body[data-ct="app"] a.btn,
  body[data-ct="app"] .btn-primary,
  body[data-ct="app"] .btn-secondary,
  body[data-ct="app"] .btn-teal,
  body[data-ct="app"] .btn-outline,
  body[data-ct="app"] .result-btn,
  body[data-ct="app"] .ans-btn,
  body[data-ct="app"] .choice-btn,
  body[data-ct="app"] .next-btn,
  body[data-ct="app"] .c-btn,
  body[data-ct="app"] [role="button"],
  body[data-ct="app"] select,
  body[data-ct="app"] input:not([type="checkbox"]):not([type="radio"]):not([type="range"]) {
    min-height: var(--ct-tap);
  }

  /* Standalone text links — "learn more", the back link out of the evidence
     layer, the policy links under the cookie banner — are navigation, not
     prose, so they get a real hit box even though they are not buttons.
     Inline citation links inside a sentence are deliberately excluded: WCAG
     2.5.8 exempts them, and padding them out would wreck the line spacing of
     the paragraph they sit in. */
  body[data-ct="app"] .sci-more,
  body[data-ct="app"] .sci-back,
  body[data-ct="app"] .back-link,
  body[data-ct="app"] .btn-sm,
  body[data-ct="app"] .top-bar a,
  body[data-ct="app"] .header a,
  body[data-ct="app"] .hero a,
  body[data-ct="app"] footer a,
  body[data-ct="app"] .footer a {
    display: inline-flex;
    align-items: center;
    min-height: var(--ct-tap);
  }

  /* Square-ish icon buttons need the floor on BOTH axes — a 43px-wide
     button that is 56px tall still misses the target. */
  /* The long tail of small targets turned out to be bare, class-less <a>
     elements — "登入", "我的記錄", "← 返回主頁", the citation links in the
     evidence layer — sitting at roughly 22px tall in whatever div they were
     written into. There is no class to hook, so hook the absence of one.
     Vertical padding rather than min-height: padding is part of an inline
     box's hit area, so the target grows to ~44px without altering line
     height, wrapping, or the rhythm of a paragraph the link sits inside.
     13px, not 11: in landscape the smaller base size gives a 21px line box,
     and 11px of padding landed every one of these on 43px — one pixel under
     the floor, and invisible to anything but measurement.
     Two-character links stay narrow, which clears WCAG 2.5.8 AA (24x24)
     though not AAA (44x44); widening them would push the surrounding text
     around for a link that reads fine as text. */
  body[data-ct="app"] a[href]:not([class]) { padding-block: 13px; }

  body[data-ct="app"] .notif-close,
  body[data-ct="app"] .sci-lang,
  body[data-ct="app"] .sci-langbtn-std,
  body[data-ct="app"] .icon-btn,
  body[data-ct="app"] .c-iconbtn,
  body[data-ct="app"] .qr-icon-btn,
  body[data-ct="app"] .font-toggle-btn,
  body[data-ct="app"] .contrast-toggle-btn {
    min-width: var(--ct-tap);
    min-height: var(--ct-tap);
    width: auto;
    height: auto;
  }

  /* Answer and level grids: the extra width goes into bigger targets,
     never into more columns. Two large choices beat four small ones for
     this audience. */
  body[data-ct="app"] .answer-grid,
  body[data-ct="app"] .level-grid,
  body[data-ct="app"] .choices {
    gap: calc(10px * var(--ct-pad));
  }
  body[data-ct="app"] .ans-btn,
  body[data-ct="app"] .choice-btn {
    min-height: calc(var(--ct-tap) * 1.35);
  }
}

/* ── Spending the leftover height ─────────────────────────────
   A question and four answers do not fill 1180px of iPad portrait. Left
   alone the game sits jammed against the top with half the screen empty.
   The instinct is to centre the block; the better answer for this audience
   is to let the answer buttons grow into the space. A 110px-tall target is
   worth more to someone with a tremor or poor near vision than 300px of
   tidy whitespace is to anyone. */
@media (min-width: 700px) and (orientation: portrait) {
  body[data-ct="app"] .ans-btn,
  body[data-ct="app"] .choice-btn {
    min-height: calc(var(--ct-tap) * 2);
  }
  body[data-ct="app"] .q-card {
    padding-top: calc(28px * var(--ct-pad));
    padding-bottom: calc(28px * var(--ct-pad));
  }
}

/* ── Bottom navigation ────────────────────────────────────────
   Stretched edge to edge on a 1194px screen the nav becomes five tiny
   islands with 10px labels a metre apart. Pull it back to a centred bar
   that matches the content column, and enlarge it. */
@media (min-width: 700px) {
  /* Two nav implementations exist and they do not agree: most pages pin
     .bnav / .bnav-dark to the bottom, but object-sort and orientation leave
     it in normal flow, where on a tall iPad it simply floats at the end of
     the document. Normalising to fixed here is what lets the accessibility
     bar dock above it with a known clearance, and it is the behaviour the
     other pages already have.
     Centring is done with auto inline margins rather than the usual
     left:50% + translateX(-50%): a transform on a static element shifts it
     by half its own width regardless of position, which pushed the whole
     nav off the left edge of the screen on exactly those two pages. Auto
     margins centre a fixed box with both insets set AND a static one. */
  body[data-ct="app"] .bnav-dark,
  body[data-ct="app"] .bnav,
  body[data-ct="app"] .c-nav {
    position: fixed;
    bottom: 0;
    inset-inline: 0;
    z-index: 100;
    width: min(var(--ct-max), 100%);
    margin-inline: auto;
    border-radius: 20px 20px 0 0;
    border-left: 1px solid rgba(255, 255, 255, .10);
    border-right: 1px solid rgba(255, 255, 255, .10);
  }
  body[data-ct="app"] .bnav-dark .bnav-item,
  body[data-ct="app"] .bnav a,
  body[data-ct="app"] .c-nav a {
    padding-top: 14px;
    padding-bottom: 12px;
    min-height: var(--ct-tap);
  }
}

/* Nav colour is owned by careiti-album.css and must NOT be set here.
   This file used to raise the inactive label to rgba(255,255,255,.72),
   which was right while the bar was near-black. The album layer then made
   the bar warm white — and because this stylesheet loads AFTER it, the
   white text survived and won: 1.02:1, invisible, on every page carrying
   the bar. Foreground and background must be owned by the same layer, or
   changing one silently orphans the other. */

/* ── Accessibility bar ────────────────────────────────────────
   The bar carries 大字模式 / 高對比 / 朗讀 — the three controls this
   audience actually needs. It should grow with everything else. */
/* Placement history, because both wrong answers were instructive.
   It began as a vertical stack floating bottom-right. On a tablet that
   corner is the answer column, and measurement caught it covering 23x85px
   of a live answer button — a control an elder cannot press.
   The fix was a full-width bar docked above the nav. That removed the
   occlusion and replaced it with permanent chrome: on the games hub the
   same bar now sat across the card grid, and it was present, at full size,
   on every page of the product.
   Third answer, and the one the user actually asked for: a collapsed tab
   pinned to the side edge. At rest it is one small control that overlaps
   nothing; pressed, it expands into the three buttons. Persistent
   availability without persistent footprint — the accessibility controls
   have to be reachable everywhere, but they do not have to be *open*
   everywhere.
   Collapse state is driven by careiti-a11y.js via [data-ca11y-open]. */
@media (min-width: 700px) {
  body[data-ct="app"] .ca11y-bar {
    flex-direction: column;
    gap: 6px;
    padding: 6px;
    border-radius: 14px 0 0 14px;
    left: auto;
    right: 0;
    transform: none;
    top: 50%;
    bottom: auto;
    translate: 0 -50%;
    border-right: none;
    background: var(--print, #FFFDF8);
    border: 1px solid var(--rule, #DFD3BE);
    box-shadow: -4px 0 18px rgba(58, 42, 20, .10);
  }
  /* Collapsed: only the handle shows. */
  body[data-ct="app"] .ca11y-bar:not([data-ca11y-open="1"]) .ca11y-btn { display: none; }
  body[data-ct="app"] .ca11y-bar:not([data-ca11y-open="1"]) { padding: 4px; }
  body[data-ct="app"] { padding-bottom: 110px; }
  body[data-ct="app"] .ca11y-btn {
    flex-direction: row;
    gap: 8px;
    min-width: 128px;
    padding: 6px 12px;
    min-height: var(--ct-tap);
    justify-content: flex-start;
  }
  /* The handle itself — always visible, always the same place. */
  body[data-ct="app"] .ca11y-handle {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 56px;
    border: none;
    background: transparent;
    color: var(--teal-ink, #0B6E64);
    cursor: pointer;
    border-radius: 10px;
  }
  body[data-ct="app"] .ca11y-handle svg { width: 22px; height: 22px; }
  body[data-ct="app"] .ca11y-btn svg { width: 26px; height: 26px; }
  /* careiti-a11y.css is left out of the px transform on purpose (it pins the
     bar compact under 大字模式), so its label size is restated here through
     the same ramp — including the floor. A 10px label on the button that
     turns on 大字模式 is a particularly bad place to have unreadable text. */
  body[data-ct="app"] .ca11y-btn span,
  body[data-ct="app"] .ca11y-bar {
    font-size: max(calc(10px * var(--ct-k1, 1)), var(--ct-min, 0px));
  }
}

/* ── Gameplay in short landscape ──────────────────────────────
   Portrait has the height to keep question above answers, which is the
   layout that asks least of the reader. Landscape does not: at 834px the
   select and play screens overflow, and an elder answering a question
   they can no longer see has lost the task. So in short landscape only,
   the question moves left and the answers right — both stay on screen,
   the answer grid keeps its 2×2 shape, and eye travel stays short. */
@media (min-width: 900px) and (max-height: 900px) and (orientation: landscape) {
  /* The games show and hide their screens with an INLINE style — a page
     writes el.style.display = 'flex' (or 'block') when a round starts. An
     inline declaration beats any stylesheet rule, so a plain `display:grid`
     here would be silently discarded the moment play actually began, and
     the two-column layout would only ever appear in a test harness that
     cleared the attribute.
     `!important` is correct here precisely because the inline value is
     carrying visibility, not layout. It is gated on the element not being
     hidden — matching both the `display:none;` written in the markup and
     the `display: none;` Chrome serialises from JS — so hiding still wins
     and a hidden screen can never be forced open. */
  body[data-ct="app"] #gameArea:not([style*="display:none"]):not([style*="display: none"]),
  body[data-ct="app"] #screenPlay:not([style*="display:none"]):not([style*="display: none"]),
  body[data-ct="app"] .play-wrap:not([style*="display:none"]):not([style*="display: none"]) {
    display: grid !important;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    column-gap: clamp(20px, 3vw, 36px);
    row-gap: 12px;
    /* The accessibility bar floats over the bottom-right corner. In the
       two-column layout that corner is the answer column, and a measured
       ~30px of the last answer ended up underneath it — an answer an elder
       cannot press. The content column is pulled in far enough to clear the
       bar on both sides rather than moving the bar, because a control that
       changes position between orientations is its own usability problem. */
    max-width: min(calc(100vw - 260px), 1000px);
    /* Landscape is where height is scarce, so here the leftover space is
       taken by centring rather than by growing the targets — the question
       lands at eye level instead of clinging to the top edge. */
    align-content: center;
    min-height: calc(100vh - 320px);
    min-height: calc(100dvh - 320px);
  }
  /* 1.3, not the portrait 2.0: the iPad mini in landscape is the shortest
     viewport the app ever sees (744px) and measurement had emoji-quiz
     overflowing it by 17px at 1.5. Targets stay well above the 52px floor;
     the height goes to keeping the question on screen. */
  body[data-ct="app"] .ans-btn,
  body[data-ct="app"] .choice-btn { min-height: calc(var(--ct-tap) * 1.3); }

  /* Anything not explicitly placed spans the full width, so an unknown
     child can never be silently dropped into the wrong cell. */
  body[data-ct="app"] #gameArea > *,
  body[data-ct="app"] #screenPlay > *,
  body[data-ct="app"] .play-wrap > * { grid-column: 1 / -1; }

  /* Left: the thing being asked. */
  body[data-ct="app"] #gameArea > .q-card,
  body[data-ct="app"] #screenPlay > .q-card,
  body[data-ct="app"] #screenPlay > .items-pool,
  body[data-ct="app"] .play-wrap > .q-card,
  body[data-ct="app"] .play-wrap > .items-pool {
    grid-column: 1;
    align-self: start;
    margin-bottom: 0;
  }

  /* Right: the thing being chosen. */
  body[data-ct="app"] #gameArea > .answer-grid,
  body[data-ct="app"] #screenPlay > .choices,
  body[data-ct="app"] #screenPlay > .cats-grid,
  body[data-ct="app"] .play-wrap > .choices,
  body[data-ct="app"] .play-wrap > .cats-grid {
    grid-column: 2;
    align-self: start;
    margin-bottom: 0;
  }

  /* Level pickers get a third column here — in landscape the constraint
     is vertical, and a level grid is scanned once, not read. */
  body[data-ct="app"] .level-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }

  /* The hero eats scarce height on a screen this short. */
  body[data-ct="app"] .hero { padding-top: 18px; padding-bottom: 20px; }
}

/* ── Touch: no sticky hover ───────────────────────────────────
   Handled at source by wrapping each hover rule in @media (hover:hover);
   this is the belt-and-braces half — a pointer that cannot hover also
   should not animate lift effects that only read as hover feedback. */
@media (hover: none) {
  body[data-ct="app"] .ans-btn,
  body[data-ct="app"] .choice-btn,
  body[data-ct="app"] .level-card,
  body[data-ct="app"] .lv-card { transform: none; }
}

/* ── Reduced motion ───────────────────────────────────────────
   Vestibular sensitivity rises with age and this is a product for 65+,
   so the system preference is honoured here as well as per page. */
@media (prefers-reduced-motion: reduce) {
  body[data-ct="app"] * {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .05ms !important;
    scroll-behavior: auto !important;
  }
}

@media print {
  body[data-ct="app"] .ca11y-bar,
  body[data-ct="app"] .bnav-dark,
  body[data-ct="app"] .bnav { display: none !important; }
}
