/* The reader.
   ---------------------------------------------------------------------------
   Three layouts, and they are not skins of one another:

     [data-direction="ltr"|"rtl"]  paged — one page at a time
     [data-direction="vertical"]   the webtoon strip — pages stacked, scrolled
     [data-direction="scrolled"]   reflowable EPUB — prose, one spine document

   ⚠ RTL is not a mirrored LTR. The pages are in the other order and the
   controls mean the opposite thing; `reader-view.js` inverts at the input
   boundary so everything below stays direction-agnostic, and this file only has
   to lay the chrome out the other way round.

   ---------------------------------------------------------------------------
   The reading options (js/reader/settings.js) arrive as attributes and custom
   properties on `#reader-host`. That is the point of the split: everything
   except the reading mode and the prose layout is PURE CSS, so changing a font
   size or a fit mode repaints nothing and therefore cannot lose the place.

     [data-fit]          screen | width | height | original
     [data-surface]      black | grey | white
     [data-gap]          none | thin          (continuous mode)
     [data-text-layout]  scroll | paged       (reflowable prose)
     [data-text-theme]   night | sepia | paper
     [data-text-font]    serif | sans
     [data-justify]      on | off
     [data-tap]          edge | kindle | l-shape | off
     [data-zoomed]       on | off            (set by zoom.js, not a preference)
     --rd-font-size · --rd-line-height · --rd-measure · --rd-col-w
     --rd-zoom · --rd-pan-x · --rd-pan-y     (zoom.js)
     --rd-inset-top · --rd-inset-bottom      (what the chrome is stealing)

   ⚠ Two-up spreads are the exception to "everything else is pure CSS": `spread`
   changes which pages `paintPage` renders, so it is STRUCTURAL and goes through
   the teardown-and-repaint path. It is safe there only because the stored
   position is a page index rather than a pixel offset (ARCHITECTURE.md §9.1).

   ⚠ The token defaults live on bare `#reader-host`, NOT inside the
   `:not([hidden])` block below. `:not()` carries its argument's specificity, so
   `#reader-host:not([hidden])` is (1,2,0) and would beat every
   `#reader-host[data-surface="…"]` override at (1,1,0) — the surround would be
   stuck on black with the buttons all lighting up correctly.
*/
#reader-host {
  --rd-surface: #08070a;
  --rd-col-gap: 48px;
  --rd-page-bg: #12100e;
  --rd-page-fg: #e8e2d8;
}
#reader-host[data-surface="grey"] { --rd-surface: #2b2b2e; }
#reader-host[data-surface="white"] { --rd-surface: #e9e6e0; }

/* Prose themes. A book is read for hours; night is the default because the rest
   of the app is dark and a white slab in a dark room is the complaint people
   actually have — but sepia and paper exist because the same argument runs the
   other way in daylight. */
#reader-host[data-text-theme="sepia"] { --rd-page-bg: #f3ead6; --rd-page-fg: #4a3f2e; }
#reader-host[data-text-theme="paper"] { --rd-page-bg: #fbfaf7; --rd-page-fg: #1b1917; }

/* The chrome follows the page, not the app. A dark translucent bar over a sepia
   page is a grey band across the top of the book — the one element that does not
   belong to either. */
/* ⚠ Opaque. At 0.55–0.62 the line of text under the bottom bar read straight
   through it and collided with the ‹ ☰ › buttons (seen on a phone); even 0.95
   left a legible ghost of dark text on a light page. */
#reader-host { --rd-chrome-bg: #14120f; --rd-chrome-fg: var(--fg); --rd-chrome-dim: var(--muted); --rd-chrome-btn: rgba(255, 255, 255, 0.08); --rd-chrome-line: rgba(255, 255, 255, 0.08); }
#reader-host[data-direction="scrolled"][data-text-theme="sepia"],
#reader-host[data-direction="scrolled"][data-text-theme="paper"] {
  --rd-chrome-bg: #f4f1ea;
  --rd-chrome-line: rgba(50, 42, 32, 0.12);
  /* White-on-white was invisible: the chapter buttons need a dark tint here. */
  --rd-chrome-btn: rgba(50, 42, 32, 0.08);
  --rd-chrome-fg: #322a20;
  --rd-chrome-dim: #6d6255;
}

/* For prose the surround IS the page — there is no artwork to frame, so the
   theme owns the whole stage. Placed after the `[data-surface]` rules on
   purpose: equal specificity, later wins. */
#reader-host[data-direction="scrolled"] { --rd-surface: var(--rd-page-bg); }

/* ⚠ `[hidden]` is only `display: none` from the UA stylesheet, so ANY author
   `display` rule beats it. `#reader-host` is `position: fixed; inset: 0` and sits
   above everything, so an unguarded `display: flex` here paints an opaque
   full-screen panel over the entire app — with the real content still in the DOM
   and every query for it succeeding. The symptom is a black page and a passing
   snapshot, which is about as misleading as a CSS bug gets.

   Since v2 the host declares NO `display` at all — the stage and the chrome are
   absolutely positioned inside it, so a `<section>`'s default `block` is all it
   needs and the UA's `[hidden]` wins unopposed. The trap is gone rather than
   guarded. The rule below stays as the belt to that brace: it costs nothing and
   the failure it prevents is invisible. */
#reader-host[hidden] { display: none !important; }

#reader-host:not([hidden]) {
  position: fixed;
  inset: 0;
  /* ⚠ `dvh` as well as `inset`, and they are not redundant. A fixed element
     resolves against the LAYOUT viewport, which on mobile Safari and Chrome sits
     underneath the collapsing URL bar; `100dvh` tracks the bar as it moves. The
     `inset` is the fallback for anything without `dvh`. */
  height: 100dvh;
  /* ⚠ Never SHORTER than the measured visible height (`trackViewport`): `dvh` alone
     left a band of the page showing under the reader on some Android windows. */
  height: max(100dvh, var(--rd-vh, 0px));
  z-index: 60;
  /* Near-black behind a page by default: a page is mostly white, and a warm
     surround around it reads as a colour cast on the artwork. */
  background: var(--rd-surface);
}
body.reading { overflow: hidden; }

/* ---------------------------------------------------------------------------
   The stage
   ---------------------------------------------------------------------------
   ⚠ **Absolutely positioned, and that is the whole point of v2.**

   Until v2 the stage was `flex: 1` between two `flex: none` bars, and immersive
   mode hid those bars with `opacity` + `visibility` + `transform` — none of
   which release layout space. So the stage was permanently `100vh − 2 × bar`,
   chrome up or chrome down: you got the undistracted look and none of the
   height. Taking the chrome out of flow is what actually gives the page the
   screen.

   It buys a second thing that is easy to miss: the stage box is now CONSTANT.
   Showing or hiding the chrome cannot resize it, so the `ResizeObserver` in
   `reader-view.js` fires only on a real window resize instead of on every
   toggle — and a resize there means re-measuring columns and re-anchoring the
   reader's place in the text. */
.rd-stage {
  position: absolute;
  inset: 0;
  overflow: auto;
  display: grid;
  place-items: center;
  outline: none;
  /* ⚠ So `scrollIntoView` (the webtoon strip's `scrollCellIntoView`) lands the
     cell BELOW a shown top bar rather than under it. The JS half of the same
     correction is `stageInset()` in `reader-view.js`, which the sites that
     measure against the stage's own edge consult. */
  scroll-padding-top: var(--rd-inset-top, 0px);
  scroll-padding-bottom: var(--rd-inset-bottom, 0px);
}

/* ---------------------------------------------------------------------------
   Chrome
   ---------------------------------------------------------------------------
   Overlays, never flow. Two axes are used, and which one is free depends on the
   screen rather than on a breakpoint:

     a 0.7-aspect page on a 16:9 desktop is HEIGHT-bound — it leaves ~580px of
     empty pillar down each side, which is where `.rd-nav-*` lives;

     the same page on a portrait phone is WIDTH-bound — it leaves ~145px of
     letterbox top and bottom, which is where the bars live.

   So the bars go on the horizontal edges and the turn controls on the vertical
   edges, and on both form factors the chrome sits in space the page was never
   going to use. No layout fork is needed for that; the only thing that forks is
   whether hover exists (see `.rd-nav-*`).

   ⚠ `--rd-inset-*` is the height the chrome is currently STEALING from readable
   content, and it must be 0 whenever the chrome is hidden. Three sites in
   `reader-view.js` measure against the stage's own top edge — the strip's scroll
   cursor, the prose resume anchor and the keyboard page unit — and a full-bleed
   stage puts that edge at y=0. Without the inset they would each silently answer
   "the thing under the bar". */
#reader-host { --rd-inset-top: 0px; --rd-inset-bottom: 0px; }
#reader-host:not(.rd-immersive) {
  --rd-inset-top: calc(46px + env(safe-area-inset-top));
  --rd-inset-bottom: calc(46px + env(safe-area-inset-bottom));
}

/* The container is inert; every control inside it opts back in. A tap on the
   bar's empty background must fall through to the page, or the widest part of
   the chrome becomes a dead strip across the top of the book. */
.rd-chrome { position: absolute; inset: 0; pointer-events: none; z-index: 1; }
.rd-chrome > * { pointer-events: auto; }

.rd-bar-top, .rd-bar-bottom {
  position: absolute;
  left: 0; right: 0;
  display: flex; align-items: center; gap: 12px;
  padding: 8px 14px;
  padding-left: max(14px, env(safe-area-inset-left));
  padding-right: max(14px, env(safe-area-inset-right));
  background: var(--rd-chrome-bg);
  backdrop-filter: blur(8px);
  color: var(--rd-chrome-fg);
  transition: opacity 0.15s ease, transform 0.15s ease;
}
/* ⚠ The notch and the home indicator. `viewport-fit=cover` is set in
   index.html, so without these the close button sits under the camera housing
   and the scrub under the gesture bar. */
/* The hairline is a shadow, not a border: a border adds 1px to the bar and the
   `--rd-inset-*` arithmetic counts the bar's exact height. */
.rd-bar-top { top: 0; padding-top: calc(8px + env(safe-area-inset-top)); box-shadow: 0 1px 0 var(--rd-chrome-line); }
.rd-bar-bottom { bottom: 0; padding-bottom: calc(8px + env(safe-area-inset-bottom)); box-shadow: 0 -1px 0 var(--rd-chrome-line); }

/* Two lines: the work, then the instalment ("Vol. 2 · Ch. 12 · The Northern
   Road") smaller beneath it. Each truncates on its own, so a long chapter name
   never pushes the series off the bar.
   ⚠ Sized to stay inside the bar's declared 46px (`--rd-inset-top`): at 1.1
   line-height the two lines are ~28px, the height of the 20px icon buttons
   beside them. A taller title grows the bar under content inset for 46px. */
.rd-title { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.1; }
.rd-title-work, .rd-title-sub { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rd-title-sub { font-size: 11px; opacity: 0.75; }
.rd-title-sub[hidden] { display: none; }
.rd-back, .rd-options, .rd-full, .rd-chap-prev, .rd-chap-next {
  background: none; border: none; color: var(--rd-chrome-fg);
  font-size: 20px; line-height: 1; cursor: pointer; padding: 4px 10px;
}
.rd-options, .rd-full { font-size: 17px; opacity: 0.85; }
.rd-options:hover, .rd-options:focus-visible,
.rd-full:hover, .rd-full:focus-visible { opacity: 1; }
.rd-chap-prev, .rd-chap-next {
  font-size: 15px; opacity: 0.85;
  display: inline-flex; align-items: center; gap: 6px;
}
.rd-chap-prev[disabled], .rd-chap-next[disabled] { opacity: 0.25; cursor: default; }
/* The chapter ordinal. Hidden on a fine pointer, where the bar keeps its compact
   glyph-only form and the button's tooltip names the chapter; shown on touch
   (see the Touch block), where a tooltip is never seen. */
.rd-chap-label {
  display: none;
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.rd-chap-glyph { display: inline-block; }
.rd-chaps {
  background: none; border: none; color: var(--rd-chrome-fg);
  font-size: 17px; line-height: 1; cursor: pointer; padding: 4px 8px; opacity: 0.85;
}
.rd-chaps:hover, .rd-chaps:focus-visible { opacity: 1; }
.rd-scrub { flex: 1; accent-color: var(--accent); min-width: 0; }
/* The page the thumb is over, shown only while it is being dragged (or
   stepped). `left`/`top` are set from the input's box in `showScrubTip`; the
   transform lifts it clear of the thumb, where a finger is not covering it. */
.rd-scrub-tip {
  position: absolute;
  transform: translate(-50%, calc(-100% - 10px));
  padding: 3px 9px;
  border-radius: 6px;
  background: var(--rd-chrome-bg);
  color: var(--rd-chrome-fg);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.12s ease;
}
#reader-host.rd-scrubbing .rd-scrub-tip { opacity: 1; }

/* ---------------------------------------------------------------------------
   The page pill — the one piece of chrome that survives the hide
   ---------------------------------------------------------------------------
   Every reader in this category keeps a page counter visible in immersive mode
   (Tachiyomi calls it "show page number", Kindle keeps a location line), and the
   reason is that it is the one fact you glance at without wanting to act on it.
   Dimmed rather than hidden, and it doubles as the affordance that summons the
   scrub — which is the only control that genuinely needs the full width, and so
   is the only one worth summoning.

   ⚠ `.rd-pos` is also rewritten by `paintDoc` once the column label is
   knowable; both writers build the text with `posText`. Keep the element. */
.rd-pos {
  position: absolute;
  bottom: calc(10px + env(safe-area-inset-bottom));
  right: max(14px, env(safe-area-inset-right));
  font-size: 12px;
  color: var(--rd-chrome-fg);
  background: var(--rd-chrome-bg);
  border: none; border-radius: 999px;
  padding: 5px 11px;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  opacity: 0.55;
  transition: opacity 0.15s ease;
}
.rd-pos:hover, .rd-pos:focus-visible { opacity: 1; }
/* In RTL the pill moves with the text it counts. */
#reader-host[data-direction="rtl"] .rd-pos {
  right: auto;
  left: max(14px, env(safe-area-inset-left));
}
/* The bottom bar and the pill occupy the same corner; only one is ever up. */
#reader-host:not(.rd-immersive) .rd-pos { opacity: 0; visibility: hidden; }

/* ---------------------------------------------------------------------------
   Edge turn controls
   ---------------------------------------------------------------------------
   Vertically centred at the left and right edges, which on a landscape screen is
   the pillarbox — free space by construction. These are SPATIAL controls: unlike
   the ‹ › that used to live in the bottom bar they are placed by where the page
   moves, so RTL swaps which one advances (`reader-view.js` inverts at the input
   boundary and the glyphs follow).

   ⚠ Hidden entirely on a coarse pointer, following `.strip-arrow` in mobile.css:
   touch has no hover, so an affordance revealed by hover is simply invisible
   there — and on touch the tap zones already do this job better. */
.rd-nav-prev, .rd-nav-next {
  position: absolute;
  top: 50%; transform: translateY(-50%);
  width: 48px; height: 48px;
  display: grid; place-items: center;
  border: none; border-radius: 50%;
  background: var(--rd-chrome-bg);
  backdrop-filter: blur(6px);
  color: var(--rd-chrome-fg);
  font-size: 22px; line-height: 1; cursor: pointer;
  transition: opacity 0.15s ease;
}
.rd-nav-prev { left: max(12px, env(safe-area-inset-left)); }
.rd-nav-next { right: max(12px, env(safe-area-inset-right)); }
#reader-host[data-direction="rtl"] .rd-nav-prev,
#reader-host[data-direction="rtl"] .rd-nav-next { transform: translateY(-50%) scaleX(-1); }

/* ---------------------------------------------------------------------------
   Immersive — the default state, not the toggled one
   ---------------------------------------------------------------------------
   ⚠ `visibility` as well as opacity: a bar that is invisible but still
   hit-testable swallows the tap that would bring it back.

   ⚠ And `pointer-events: none` on the container as well, because the nav
   buttons are 48px circles sitting exactly over the left and right tap zones. A
   hidden circle that still eats clicks makes the page stop turning in the two
   places the reader taps most. */
#reader-host.rd-immersive .rd-chrome { pointer-events: none; }
#reader-host.rd-immersive .rd-bar-top { opacity: 0; visibility: hidden; transform: translateY(-100%); }
#reader-host.rd-immersive .rd-bar-bottom { opacity: 0; visibility: hidden; transform: translateY(100%); }
#reader-host.rd-immersive .rd-nav-prev,
#reader-host.rd-immersive .rd-nav-next { opacity: 0; visibility: hidden; }

/* ⚠ In RTL the scrub runs the other way too. A slider whose left end is the
   *last* page is not a styling nicety — it is the difference between a control
   that matches the page turn and one that fights it. */
#reader-host[data-direction="rtl"] .rd-scrub { direction: rtl; }

/* The chapter buttons keep their MEANING (previous/next in reading order) and
   swap their position and their glyph, so the arrow always points the way the
   chapters actually run. Reversing the row without swapping the glyphs would
   leave a `»` on the left meaning "back", which is worse than not flipping. */
#reader-host[data-direction="rtl"] .rd-bar-bottom { flex-direction: row-reverse; }
/* ⚠ The GLYPH flips, never the whole button: the button now carries a text
   label ("Ch. 11"), and `scaleX(-1)` on the button would mirror that too. The
   button's own row reverses instead, so the arrow stays on the outer edge. */
#reader-host[data-direction="rtl"] .rd-chap-prev,
#reader-host[data-direction="rtl"] .rd-chap-next { flex-direction: row-reverse; }
#reader-host[data-direction="rtl"] .rd-chap-glyph { transform: scaleX(-1); }

/* The tap zones are invisible but they are a pointing device's affordance, so
   say so. ⚠ `:not([data-tap="off"])` rather than `[data-tap="on"]`: `tapZones`
   became a preset NAME in v2 (`edge` | `kindle` | `l-shape` | `off`) and the
   old `="on"` selector would now match none of them. */
#reader-host[data-tap]:not([data-tap="off"])[data-direction="ltr"] .rd-stage,
#reader-host[data-tap]:not([data-tap="off"])[data-direction="rtl"] .rd-stage { cursor: pointer; }
/* Panning owns the pointer once the page is zoomed past fit. */
#reader-host[data-zoomed="on"] .rd-stage { cursor: grab; }
#reader-host[data-zoomed="on"] .rd-stage:active { cursor: grabbing; }

/* ---------------------------------------------------------------------------
   Fit — the paged page image
   ---------------------------------------------------------------------------
   Four modes, and only the first one fits inside the stage. The other three
   deliberately overflow it and let the stage scroll, because that is what
   "fit width" MEANS on a tall scan: fill the width and scroll down the page.
   Constraining them back to the viewport would silently turn all four into
   one. */
.rd-page { display: block; }

/* Fit screen — the default. Both axes bounded, and never upscaled past the
   image's own pixels: a 900px scan blown up to a 4K viewport is worse than a
   smaller sharp one. */
#reader-host[data-fit="screen"] .rd-page {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}
#reader-host[data-fit="width"] .rd-page { width: 100%; height: auto; }
#reader-host[data-fit="height"] .rd-page { height: 100%; width: auto; }
/* Original: the scan's own pixels, whatever they are. The one mode where a
   double-page spread stays legible on a large display. */
#reader-host[data-fit="original"] .rd-page { max-width: none; max-height: none; }

/* An overflowing page must start at the top-left corner it is read from, not be
   centred with its head cut off. */
#reader-host[data-fit="width"] .rd-stage,
#reader-host[data-fit="original"] .rd-stage { align-items: start; }
#reader-host[data-fit="height"] .rd-stage,
#reader-host[data-fit="original"] .rd-stage { justify-items: start; }

/* ---------------------------------------------------------------------------
   Two-up spreads
   ---------------------------------------------------------------------------
   The desktop half of "use the whole screen". A portrait page on a 16:9 display
   is height-bound and leaves most of the width empty; two of them side by side
   is what that width is for, and it is how the book was printed.

   ⚠ The pair is laid out in READING order and then reversed for RTL, rather
   than being built in screen order. Same rule as everywhere else in this file:
   the renderer stays direction-agnostic and the flip happens at one boundary.
   Building it in screen order would put page 5 to the left of page 4 in a manga
   and read as a corrupted scan.

   ⚠ A `double` spread is NOT `fit: width` twice. Each page is bounded by HALF
   the stage width and the whole stage height, so the pair fits the screen the
   way one page does in `fit: screen`. */
/* ⚠ **Bound the pages in VIEWPORT units, not percentages.**
   `.rd-page` used to be the grid item itself, and `max-height: 100%` resolved
   against the grid area. Wrapping it — for the pair, and for the zoom
   transform — broke that chain in a way that is worth spelling out, because the
   obvious fixes do not work:

     the stage is `display: grid` with an implicit AUTO row, so the grid area is
     sized to its content. A percentage height on the wrapper therefore resolves
     against a track that is itself sized from the wrapper — circular. Chrome
     resolves it to the content height, so `height: 100%` came back as 1200px on
     a 900px screen and `max-height: 100%` inside it became 1200px too. Every
     page rendered at its natural pixel size, overflowing the screen it was
     meant to fit, with no rule anywhere reading as wrong.

   The stage is `position: fixed; inset: 0` on a host that is the whole viewport,
   so `dvh`/`vw` are not an approximation here — they are exactly the stage box,
   and they are definite whatever the grid does. */
.rd-spread {
  display: flex; align-items: center; justify-content: center; gap: 0;
  max-width: 100vw;
}

/* ⚠ Reading order, then reversed for RTL — never built in screen order. */
#reader-host[data-direction="rtl"] .rd-spread { flex-direction: row-reverse; }

/* Each page of a PAIR is bounded by half the stage, so the two together fit the
   screen the way one page does on its own. A lone page — the cover before the
   pairing starts, the last odd page, or a wide page that is already a spread in
   the scan — keeps the full width rather than sitting in a half-width column
   with a gap beside it. */
.rd-spread[data-single="off"] .rd-page { max-width: 50vw; }
.rd-spread[data-single="on"] .rd-page { max-width: 100vw; }
#reader-host[data-fit="screen"] .rd-spread .rd-page { max-height: 100dvh; object-fit: contain; }
#reader-host[data-fit="height"] .rd-spread .rd-page { height: 100dvh; width: auto; }
/* `fit: width` means "fill the width", which across a pair is half each. */
#reader-host[data-fit="width"] .rd-spread[data-single="off"] .rd-page { width: 50%; height: auto; }

/* ⚠ **`original` is the one fit whose PAIR can be wider than the screen, and
   the `max-width: 100vw` above then makes half of it unreachable.** A centred
   flex box that overflows spills equally BOTH ways, and the left spill lands at
   a negative offset that no `scrollLeft` can reach: measured on a 1920-wide
   stage, the leading page of a 2×1067 spread started at x = -107 with
   `scrollLeft` bottoming out at 0, so 107px of art could not be scrolled to by
   any means. Taking the clamp off lets the stage scroll the whole spread — the
   overflow becomes scrollable width instead of a centred crop.

   Not a problem in the other three fits: they all bound the pair to the stage,
   so it never overflows horizontally in the first place. */
#reader-host[data-fit="original"] .rd-spread { max-width: none; }

/* ---------------------------------------------------------------------------
   Zoom
   ---------------------------------------------------------------------------
   ⚠ A transform, deliberately, not a width/height change. `fit` stays the base
   and zoom multiplies on top of it, so the four fit modes keep meaning what they
   mean and returning to 1× cannot land somewhere different from where the
   reader started. It also keeps the zoom off the layout path: a pinch repaints
   a composited layer and never reflows the page or re-measures a column.

   `transform-origin: center` pairs with the stage's `place-items: center`, so
   zooming a fitted page grows it about the middle of the screen rather than
   walking it off the top-left corner. */
.rd-zoomwrap {
  transform: translate(var(--rd-pan-x, 0px), var(--rd-pan-y, 0px)) scale(var(--rd-zoom, 1));
  transform-origin: center center;
  /* Not animated: a pinch drives this every frame and a transition would make it
     lag the fingers. `chrome.js` adds `.rd-zoom-eased` for the double-tap step,
     which is the one case where the change is discrete. */
  will-change: transform;
  touch-action: none;
}
.rd-zoomwrap.rd-zoom-eased { transition: transform 0.18s ease; }

/* ---------------------------------------------------------------------------
   The continuous strip
   ---------------------------------------------------------------------------
   Vertical scroll, pages butted together with no gap. A gap would read as a
   page boundary, which is exactly the model a webtoon does not have — so `thin`
   exists for the case the source is a scanned COMIC being read continuously,
   where the boundary is real. */
.rd-strip { display: block; width: min(820px, 100%); margin: 0 auto; }
.rd-cell { display: block; min-height: 50vh; }
.rd-cell img { display: block; width: 100%; margin: 0; }
/* A cell whose page could not be fetched or decoded. Not an error screen: one
   bad page in a 200-page strip must not stop the scroll. */
.rd-cell-bad {
  min-height: 120px;
  background: repeating-linear-gradient(45deg,
    rgba(224, 108, 108, 0.10) 0 12px, transparent 12px 24px);
}
#reader-host[data-gap="thin"] .rd-cell + .rd-cell { margin-top: 10px; }
#reader-host[data-fit="width"] .rd-strip { width: 100%; }
#reader-host[data-fit="original"] .rd-strip { width: max-content; }
#reader-host[data-fit="original"] .rd-cell img { width: auto; }
#reader-host[data-direction="vertical"] .rd-stage { align-items: start; }
/* ⚠ Scroll anchoring OFF in the strip, because the strip does it itself
   (`preserveAnchor` in reader-view.js): Safari has none, and where the browser
   has it, it would correct a prepended chapter or a page decoding above the
   reader a second time and throw them forward by the same amount. */
#reader-host[data-direction="vertical"] .rd-stage { overflow-anchor: none; }
/* One chapter's run of pages. A plain block: the strip reads as one surface.
   ⚠ Not `.rd-seg` — that is the options sheet's segmented control (a wrapping
   flex row), and borrowing the name laid every chapter out as rows of cells. */
.rd-chapseg { display: block; }

/* ---------------------------------------------------------------------------
   Reflowable prose
   ---------------------------------------------------------------------------
   The measure is in `em` of the reader's own size, so changing the type size
   keeps the line length in CHARACTERS put — which is the thing that actually
   governs readability. The position stays a character offset into the document;
   nothing here may be allowed to leak a pixel quantity into it. */
.rd-doc {
  color: var(--rd-page-fg);
  font-family: Georgia, "Iowan Old Style", "Times New Roman", serif;
  font-size: var(--rd-font-size, 19px);
  line-height: var(--rd-line-height, 1.62);
}
#reader-host[data-text-font="sans"] .rd-doc {
  font-family: "Segoe UI", system-ui, -apple-system, Roboto, "Helvetica Neue", sans-serif;
}
/* Justification without hyphenation is a page full of rivers, so the two ship
   together or not at all. */
#reader-host[data-justify="on"] .rd-doc { text-align: justify; hyphens: auto; }
.rd-doc img { max-width: 100%; height: auto; }
.rd-doc h1, .rd-doc h2, .rd-doc h3 { line-height: 1.25; }
.rd-doc a[data-epub-href] { color: var(--accent-2); }
/* The reader owns the page's colours (see reflow.js::scopeBookCss). That scoper
   only reaches `html`/`body` rules, so a class rule or an inline style still
   painted black on Night — `Author: Jane Austen` computed to rgb(0, 0, 0) (UX
   review 2026-09-09 §4). `!important` is what beats `style=""` and
   `<font color>`, which no sheet rewrite can reach. */
#reader-host[data-direction="scrolled"] .rd-doc *:not(a[data-epub-href]) {
  color: inherit !important;
  background-color: transparent !important;
}

/* Scrolling layout — one long column per spine document. */
#reader-host[data-direction="scrolled"] .rd-stage { align-items: start; }
#reader-host[data-text-layout="scroll"] .rd-doc {
  width: min(var(--rd-measure, 34em), 92vw);
  margin: 0 auto;
  padding: 40px 0 80px;
}

/* Paged layout — CSS columns, scrolled horizontally one screen at a time.
   ---------------------------------------------------------------------------
   ⚠ The mechanism, because it is not obvious from the declarations: a multicol
   box with a DEFINITE height and `column-fill: auto` fills column 1 to the
   bottom and then creates column 2 to its right, overflowing its own width. The
   stage is the scroll container, so the overflow becomes a horizontal scroll —
   and one column exactly as wide as the stage means one column is one page.

   ⚠ `column-width` takes a LENGTH; there is no percentage form. `--rd-col-w` is
   therefore measured in JS (`measureColumns`) and must stay in step with the
   scroll step derived from it, or every turn drifts by the difference until
   lines are cut in half. */
#reader-host[data-direction="scrolled"][data-text-layout="paged"] .rd-stage {
  display: block;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-behavior: auto;
  /* ⚠ The gutter is a transparent BORDER, not padding, and that is the whole
     trick. Overflow is clipped at the PADDING box, so with padding the columns
     that have scrolled off simply paint over the margin — you get a spread of
     two full columns plus a sliver of the third, cut mid-word, at both edges.
     A border moves the clip inward and the sliver disappears.

     Its consequence for the measurement: `clientWidth` excludes the border and
     therefore MOVES when the gutter is applied, which would make
     `measureColumns` circular. It reads `offsetWidth` instead. */
  border-left: var(--rd-gutter, 34px) solid transparent;
  border-right: var(--rd-gutter, 34px) solid transparent;
  background-clip: padding-box;
}
#reader-host[data-direction="scrolled"][data-text-layout="paged"] .rd-doc {
  height: 100%;
  margin: 0;
  padding: 28px 0;
  box-sizing: border-box;
  column-width: var(--rd-col-w, 32em);
  column-gap: var(--rd-col-gap);
  column-fill: auto;
}
/* An image taller than the column would create a column of its own and a blank
   page beside it. */
#reader-host[data-direction="scrolled"][data-text-layout="paged"] .rd-doc img {
  max-height: 82vh;
  object-fit: contain;
}
/* A picture-only document (`isPicturePage` in reader-view.js): one page, the
   picture centred and fitted. A flex container is not a multicol container, so
   the column rules above stop applying and the document is exactly one screen. */
.rd-doc.rd-doc-picture {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 12px; text-align: center;
}
#reader-host[data-text-layout="scroll"] .rd-doc.rd-doc-picture { min-height: 80dvh; }
.rd-doc.rd-doc-picture > *, .rd-doc.rd-doc-picture div { width: 100%; margin: 0; }
/* Same specificity as the paged `.rd-doc img { max-height: 82vh }` rule above
   and later, so the picture rule wins in paged layout too. */
#reader-host[data-direction] .rd-doc.rd-doc-picture img {
  width: auto; height: auto; max-width: 100%; max-height: calc(100dvh - 120px);
  object-fit: contain; margin: 0 auto; display: block;
}
/* ⚠ An SVG cover (`<svg viewBox="…" width="100%"><image …/></svg>`, what
   Calibre writes) has no intrinsic size: `width: auto` in a centred column
   collapsed it to 0×0 and the cover page was blank (seen on a phone, 1.4.2).
   It gets the box explicitly; its own `preserveAspectRatio` letter-boxes the
   picture inside. */
#reader-host[data-direction] .rd-doc.rd-doc-picture svg {
  width: 100%; height: calc(100dvh - 120px); max-width: 100%;
  margin: 0 auto; display: block;
}

/* Links on the light themes: the app's accent is a pale amber made for a dark
   page, about 2:1 against paper (a contents page read as faded). A darker amber
   of the same hue passes 4.5:1 on both light pages. */
#reader-host[data-text-theme="paper"] .rd-doc a[data-epub-href],
#reader-host[data-text-theme="sepia"] .rd-doc a[data-epub-href] { color: #8a4a12; }

/* A horizontal scrollbar under a page of prose is chrome the reader did not ask
   for; the turn is the control. */
#reader-host[data-direction="scrolled"][data-text-layout="paged"] .rd-stage::-webkit-scrollbar {
  height: 0;
}

/* ---------------------------------------------------------------------------
   The options sheet
   --------------------------------------------------------------------------- */

.rd-settings-scrim {
  position: absolute; inset: 0; z-index: 2;
  background: rgba(0, 0, 0, 0.4);
}
.rd-settings {
  position: absolute; top: 0; right: 0; bottom: 0; z-index: 3;
  width: min(340px, 88vw);
  display: flex; flex-direction: column;
  background: var(--bg-elev);
  color: var(--fg);
  border-left: 1px solid rgba(255, 255, 255, 0.08);
  box-shadow: -18px 0 44px rgba(0, 0, 0, 0.5);
}
.rd-set-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 16px; flex: none;
  font-size: var(--fs-md, 14px); font-weight: 600;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}
.rd-set-close {
  background: none; border: none; color: var(--muted);
  font-size: 16px; cursor: pointer; padding: 4px 6px;
}
.rd-set-body { flex: 1; min-height: 0; overflow: auto; padding: 6px 16px 16px; }
.rd-set-foot {
  flex: none; padding: 12px 16px;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}
.rd-set-reset {
  background: none; border: 1px solid rgba(255, 255, 255, 0.14);
  color: var(--muted); border-radius: 8px;
  padding: 7px 12px; font-size: var(--fs-sm, 12.5px); cursor: pointer;
}
.rd-set-reset:hover { color: var(--fg); border-color: rgba(255, 255, 255, 0.28); }

.rd-set-row { padding: 12px 0; border-bottom: 1px solid rgba(255, 255, 255, 0.05); }
.rd-set-row:last-child { border-bottom: none; }
.rd-set-label {
  display: flex; flex-direction: column; gap: 2px;
  font-size: var(--fs-sm, 12.5px); margin-bottom: 8px;
}
.rd-set-hint { color: var(--muted-2); font-size: var(--fs-xs, 11px); }

/* A segmented control. Wraps rather than scrolls: four options at 88vw on a
   phone do not fit on one line, and a horizontally scrolling row of buttons
   hides the last option behind an edge with nothing to say it is there. */
.rd-seg { display: flex; flex-wrap: wrap; gap: 6px; }
.rd-seg-btn {
  flex: 1 1 auto; min-width: 62px;
  background: var(--bg-card); color: var(--muted);
  border: 1px solid transparent; border-radius: 8px;
  padding: 7px 8px; font-size: var(--fs-sm, 12.5px);
  cursor: pointer; white-space: nowrap;
}
.rd-seg-btn:hover { color: var(--fg); }
.rd-seg-btn.on {
  background: var(--accent); border-color: var(--accent-2);
  color: #1a120a; font-weight: 600;
}
.rd-seg-btn:focus-visible, .rd-step:focus-visible, .rd-set-reset:focus-visible {
  outline: 2px solid var(--accent-2); outline-offset: 2px;
}

.rd-stepper { display: flex; align-items: center; gap: 10px; }
.rd-step {
  background: var(--bg-card); color: var(--fg);
  border: 1px solid transparent; border-radius: 8px;
  padding: 7px 14px; font-size: var(--fs-sm, 12.5px); cursor: pointer;
}
.rd-step[disabled] { opacity: 0.4; cursor: default; }
.rd-step-val { min-width: 34px; text-align: center; color: var(--muted); font-variant-numeric: tabular-nums; }

/* ---------------------------------------------------------------------------
   The materialise wait. Determinate on purpose: an indeterminate spinner for a
   60 MB fetch reads as a hang, and this path exists precisely because the file
   cannot be read a page at a time.
   --------------------------------------------------------------------------- */
.rd-wait { width: min(420px, 82vw); text-align: center; color: var(--muted); }
.rd-wait-label { margin-bottom: 10px; }
.rd-bar {
  height: 4px; border-radius: 999px; overflow: hidden;
  background: rgba(255, 255, 255, 0.12);
}
.rd-bar-fill { height: 100%; background: var(--accent); transition: width 0.2s linear; }
.rd-wait-why { margin-top: 12px; font-size: 12px; color: var(--muted-2); }

.rd-error { max-width: 460px; text-align: center; color: var(--err); padding: 40px; }
/* A per-page failure is not a dead chapter — a mixed-method archive's one
   unsupported entry must not read like a broken file. */
.rd-error-page { color: var(--warn); }

/* ⚠ The way out. The reader chrome is immersive from the first frame, so a bare
   sentence on a black field left the browser's own Back button as the only exit
   — see `fail()` in reader-view.js. These are wired directly on the stage and do
   not depend on the chrome ever being revealed. */
.rd-error-actions {
  display: flex; flex-wrap: wrap; gap: 10px;
  justify-content: center; margin-top: 22px;
}
.rd-error-retry {
  background: var(--accent); color: #1a120a;
  border: none; border-radius: var(--radius-sm, 8px);
  padding: 10px 20px; font-size: var(--fs-md, 14px); font-weight: 600;
  cursor: pointer;
}
.rd-error-retry:hover { background: var(--accent-2); }
.rd-error-back {
  background: none; color: var(--muted);
  border: 1px solid var(--line, #333); border-radius: var(--radius-sm, 8px);
  padding: 10px 20px; font-size: var(--fs-md, 14px);
  cursor: pointer;
}
.rd-error-back:hover { color: var(--fg); }

.rd-error-alts { margin-top: 26px; }
.rd-error-alts-label {
  color: var(--muted); font-size: var(--fs-sm, 12.5px); margin-bottom: 10px;
}
.rd-error-alt {
  background: none; color: var(--fg);
  border: 1px solid var(--line, #333); border-radius: var(--radius-sm, 8px);
  padding: 8px 14px; margin: 0 5px 8px; font-size: var(--fs-sm, 12.5px);
  cursor: pointer;
}
.rd-error-alt:hover { border-color: var(--accent); color: var(--accent); }

/* ---------------------------------------------------------------------------
   End of chapter — the break page (chapter-break.js)
   ---------------------------------------------------------------------------
   The work's poster, full-bleed and darkened, with the incoming chapter's
   number set large over it. In the strip it sits IN the flow between two
   chapters and scrolling through it is the continue; in paged mode it is the
   stage after the last page and one more turn goes on. Either way it is a
   destination, not a jump: a double-tap lands here rather than skipping a
   chapter, and it names whatever the boundary changed (a hole, a volume, a
   scanlator).

   ⚠ A FIXED height (one screen). The poster arrives after the break is laid
   out, and a break that grew when it did would move the strip under the
   reader. */
.rd-break {
  position: relative; overflow: hidden;
  width: 100%; height: 100dvh;
  display: flex; align-items: center; justify-content: center;
  color: #fff; text-align: center;
  background: linear-gradient(160deg, #2a2233 0%, #14161d 55%, #0b0c10 100%);
}
.rd-break[data-layout="paged"] { position: absolute; inset: 0; height: auto; }
.rd-break-bg {
  position: absolute; inset: -40px;
  background-size: cover; background-position: center;
  filter: blur(28px) saturate(1.15) brightness(0.42);
  transform: scale(1.08);
}
.rd-break-body {
  position: relative; max-width: 480px; padding: 32px 24px;
  display: flex; flex-direction: column; align-items: center;
}
.rd-break-ended {
  font-size: var(--fs-sm, 12.5px); letter-spacing: 0.06em; text-transform: uppercase;
  color: rgba(255, 255, 255, 0.62); margin-bottom: 18px;
}
.rd-break-poster {
  width: min(42vw, 180px); aspect-ratio: 2 / 3; object-fit: cover;
  border-radius: var(--radius-sm, 8px);
  box-shadow: 0 18px 48px rgba(0, 0, 0, 0.55);
  margin-bottom: 18px;
}
.rd-break-caption {
  font-size: var(--fs-sm, 12.5px); letter-spacing: 0.32em; text-transform: uppercase;
  color: rgba(255, 255, 255, 0.72);
}
.rd-break-num {
  font-size: clamp(72px, 22vw, 160px); font-weight: 800; line-height: 0.95;
  letter-spacing: -0.03em; font-variant-numeric: tabular-nums;
  text-shadow: 0 6px 30px rgba(0, 0, 0, 0.5);
}
.rd-break-title {
  font-size: var(--fs-lg, 17px); font-weight: 600; margin-top: 10px;
  max-width: 36ch;
}
.rd-break-note {
  margin: 10px 0 0; padding: 4px 12px; border-radius: 999px;
  font-size: var(--fs-sm, 12.5px); color: #ffd9a8;
  background: rgba(0, 0, 0, 0.35);
}
.rd-break-hint {
  margin-top: 22px; font-size: var(--fs-sm, 12.5px); color: rgba(255, 255, 255, 0.7);
}
.rd-break[data-kind="loading"] .rd-break-hint::before {
  content: ""; display: inline-block; width: 10px; height: 10px; margin-right: 8px;
  border: 2px solid rgba(255, 255, 255, 0.35); border-top-color: #fff; border-radius: 50%;
  vertical-align: -1px; animation: rd-break-spin 0.9s linear infinite;
}
@keyframes rd-break-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .rd-break[data-kind="loading"] .rd-break-hint::before { animation: none; }
}
.rd-break-actions { margin-top: 22px; }
.rd-break .rd-end-back { color: rgba(255, 255, 255, 0.62); }
.rd-break .rd-end-chaps { color: #fff; }
.rd-end { max-width: 460px; text-align: center; padding: 40px 24px; color: var(--fg); }
.rd-end-label { color: var(--muted); font-size: var(--fs-sm, 12.5px); margin-bottom: 6px; }
.rd-end-title { font-size: var(--fs-lg, 17px); font-weight: 600; margin-bottom: 20px; }
.rd-end-next {
  background: var(--accent); color: #1a120a;
  border: none; border-radius: var(--radius-sm, 8px);
  padding: 11px 22px; font-size: var(--fs-md, 14px); font-weight: 600;
  cursor: pointer;
}
.rd-end-next:hover { background: var(--accent-2); }
.rd-end-back {
  display: block; margin: 14px auto 0;
  background: none; border: none; color: var(--muted);
  font-size: var(--fs-sm, 12.5px); cursor: pointer; text-decoration: underline;
}
.rd-end-back:hover { color: var(--fg); }

/* The paged card and the strip's in-flow offer share `.rd-end`; the strip's
   sits below the last page with room to scroll it clear of the home indicator. */
.rd-end-chaps {
  display: block; margin: 14px auto 0;
  background: none; color: var(--fg);
  border: 1px solid rgba(255, 255, 255, 0.18); border-radius: var(--radius-sm, 8px);
  padding: 9px 18px; font-size: var(--fs-sm, 12.5px); cursor: pointer;
}
.rd-end-chaps:hover { border-color: rgba(255, 255, 255, 0.34); }
/* The strip's last break. Its own padding is gone: the break is a full screen
   and centres its content, which clears the home indicator by itself. */
.rd-strip-end { display: block; }

/* ---------------------------------------------------------------------------
   The chapter list
   ---------------------------------------------------------------------------
   The options sheet's twin (chapter-sheet.js says why): same side panel on a
   wide screen, a bottom sheet on touch. Head and ✕ reuse `.rd-set-*`. */
.rd-chapsheet-scrim {
  position: absolute; inset: 0; z-index: 2;
  background: rgba(0, 0, 0, 0.4);
}
.rd-chapsheet {
  position: absolute; top: 0; right: 0; bottom: 0; z-index: 3;
  width: min(360px, 88vw);
  display: flex; flex-direction: column;
  background: var(--bg-elev);
  color: var(--fg);
  border-left: 1px solid rgba(255, 255, 255, 0.08);
  box-shadow: -18px 0 44px rgba(0, 0, 0, 0.5);
}
/* `position: relative` so an item's `offsetTop` is measured from the list's own
   scroll box — `paintList` centres the current chapter with it. */
.rd-chapsheet-body { position: relative; flex: 1; min-height: 0; overflow: auto; padding: 6px 8px 16px; }
.rd-chapsheet-list { list-style: none; margin: 0; padding: 0; }
.rd-chapsheet-item {
  display: block; width: 100%; min-height: 44px;
  text-align: start;
  background: none; border: none; border-radius: 8px;
  color: var(--fg); font-size: var(--fs-md, 14px);
  padding: 11px 12px; cursor: pointer;
}
.rd-chapsheet-item:hover, .rd-chapsheet-item:focus-visible { background: var(--bg-card); }
.rd-chapsheet-item[aria-current="true"] {
  background: var(--accent); color: #1a120a; font-weight: 600;
}
.rd-chapsheet-note { color: var(--muted); font-size: var(--fs-sm, 12.5px); padding: 14px 8px; margin: 0; }

/* ---------------------------------------------------------------------------
   Touch
   ---------------------------------------------------------------------------
   Two opt-outs, both following conventions already set in css/mobile.css.
   --------------------------------------------------------------------------- */
@media (pointer: coarse) {
  /* `.strip-arrow` does the same and says why: touch has no hover, so an
     affordance gated on it is invisible — and here the tap zones already turn
     the page, better and over a far larger target. */
  .rd-nav-prev, .rd-nav-next { display: none; }

  /* ⚠ Chapter controls get their own row and a thumb-sized target. Squeezed in
     beside the scrub as bare «/» glyphs they measured about 35×23px — well
     under the ~44px a fingertip needs — and named nothing, because the name
     lived in a tooltip. Row one is ‹ Ch. 10 · ☰ · Ch. 12 ›; the scrub takes the
     whole second row, which also gives it the width it wants. */
  .rd-bar-bottom { flex-wrap: wrap; column-gap: 8px; row-gap: 6px; }
  .rd-chap-prev, .rd-chap-next, .rd-chaps {
    min-height: 44px; border-radius: 10px;
    background: var(--rd-chrome-btn);
  }
  /* The top bar's ✕, ⛶ and ⚙ measured about 30×28px: a thumb-sized target too.
     The bar grows to 8 + 44 + 8 = 60px, so the declared inset grows with it. */
  .rd-back, .rd-options, .rd-full {
    min-width: 44px; min-height: 44px;
    display: inline-flex; align-items: center; justify-content: center;
  }
  #reader-host:not(.rd-immersive) { --rd-inset-top: calc(60px + env(safe-area-inset-top)); }
  .rd-chap-prev, .rd-chap-next {
    flex: 1 1 0; min-width: 0;
    padding: 0 12px; font-size: var(--fs-md, 14px); opacity: 1;
  }
  /* A single-file book has no neighbouring chapter: an empty, disabled
     thumb-sized button on each side read as broken. Hidden, space kept, so ☰
     stays in the middle. */
  .rd-chap-prev[disabled], .rd-chap-next[disabled] { visibility: hidden; }
  .rd-chap-prev { order: 1; justify-content: flex-start; }
  .rd-chaps { order: 2; min-width: 48px; padding: 0 12px; opacity: 1; }
  .rd-chap-next { order: 3; justify-content: flex-end; }
  /* ⚠ `margin: 0` is load-bearing: Chrome's UA sheet gives a range input 2px
     top and bottom, which made the bar measure 98px against the 94px inset
     below. Zeroed rather than added in, so the arithmetic holds in every
     engine instead of matching one browser's default. */
  .rd-scrub { order: 4; flex: 1 0 100%; min-height: 28px; margin: 0; }
  .rd-chap-label { display: inline; }
  /* ⚠ The bar is two rows now, so it steals more than the 46px the base rule
     declares. `--rd-inset-bottom` is what the strip cursor, the prose anchor and
     the keyboard page unit subtract (see the note on `--rd-inset-*`); leaving it
     at 46px would count the page hidden under the scrub row as on-screen.
     8 + 44 + 6 + 28 + 8 = 94. */
  #reader-host:not(.rd-immersive) { --rd-inset-bottom: calc(94px + env(safe-area-inset-bottom)); }

  .rd-end-next, .rd-end-chaps { min-height: 44px; }

  /* A bottom sheet: the list is reached with the thumb that opened it. */
  .rd-chapsheet {
    top: auto; left: 0; width: auto; max-height: 72vh; max-height: 72dvh;
    border-left: none; border-top: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 14px 14px 0 0;
    padding-bottom: env(safe-area-inset-bottom);
    box-shadow: 0 -18px 44px rgba(0, 0, 0, 0.5);
  }
  /* mobile.css kills `backdrop-filter` on the topbar for the same reason: a
     blurred backdrop over a moving page composites every frame, and these bars
     sit over the one element that is always moving. */
  .rd-bar-top, .rd-bar-bottom, .rd-pos { backdrop-filter: none; }
}

/* Nothing here is load-bearing motion — every transition is a fade or a slide
   that has an instant end state, so honouring the preference costs no meaning. */
@media (prefers-reduced-motion: reduce) {
  .rd-bar-top, .rd-bar-bottom, .rd-nav-prev, .rd-nav-next,
  .rd-pos, .rd-scrub-tip, .rd-zoomwrap.rd-zoom-eased { transition: none; }
}
