/* Custom styles for the redesigned landing page.
   Tailwind (Play CDN) provides the utilities; this file only handles the
   bottom SEO article (which ships as a translatable HTML blob with the old
   Semantic-UI markup) plus a couple of small touches. */

/* ---------------------------------------------------------------------------
   Layout dials — how wide the content column is at each screen size.

   --rd-gutter     page gutter.
   --rd-gutter-vw  the same value expressed in vw/px, for the places it has to
                   be compared against the px-based decorative grid. Keep in
                   step with --rd-gutter.
   --rd-bleed      the gutter expressed as a % of the CONTENT width, used by the
                   full-bleed pseudo-elements to reach the page edges:
                   gutter / (100 - 2*gutter). For px gutters it is just the
                   gutter itself.
   --rd-anchor     the "logo line": the list, the reviews block and the logo all
                   pull out to this distance from the page edge once the gutter
                   grows past it, so their edges line up. 354px = 3 x 118px
                   grid cells, so it lands on a grid line.

   The gutter is a ladder, not one value. The wide 18.5% that clears space for
   ad rails only fits once the viewport can still give the server row the
   ~1083px it needs (see the .rd-card rules further down); below that a fixed
   18.5% would crush the row, so it tapers to a small fixed padding on phones.
   Effective inset per side is min(gutter, anchor).
--------------------------------------------------------------------------- */
:root {
  --rd-gutter: 16px;
  --rd-gutter-vw: 16px;
  --rd-bleed: 16px;
  --rd-anchor: 354px;
  /* Derived: the actual inset from the page edge to the content column. Custom
     properties substitute at use time, so this tracks the ladder below. */
  --rd-inset: min(var(--rd-gutter-vw), var(--rd-anchor));
}
@media (min-width: 640px)  { :root { --rd-gutter: 24px;  --rd-gutter-vw: 24px;    --rd-bleed: 24px; } }
@media (min-width: 768px)  { :root { --rd-gutter: 32px;  --rd-gutter-vw: 32px;    --rd-bleed: 32px; } }
@media (min-width: 1024px) { :root { --rd-gutter: 40px;  --rd-gutter-vw: 40px;    --rd-bleed: 40px; } }
/* Percentages from here up: 5/90, 8/84, 18.5/63. */
@media (min-width: 1280px) { :root { --rd-gutter: 5%;    --rd-gutter-vw: 5vw;     --rd-bleed: 5.5556%; } }
@media (min-width: 1536px) { :root { --rd-gutter: 8%;    --rd-gutter-vw: 8vw;     --rd-bleed: 9.5238%; } }
@media (min-width: 1920px) { :root { --rd-gutter: 18.5%; --rd-gutter-vw: 18.5vw;  --rd-bleed: 29.3651%; } }

/* Page gutter + the outward pulls that align blocks to the logo line. Plain CSS
   rather than Tailwind arbitrary values so a compiled build (README TODO 1)
   can't purge them and so the dials above are honoured in one place. */
.rd-gutter { padding-left: var(--rd-gutter); padding-right: var(--rd-gutter); }
@media (min-width: 768px) {
  .rd-edge-pull {
    margin-left: min(0px, calc(var(--rd-anchor) - var(--rd-gutter-vw)));
    margin-right: min(0px, calc(var(--rd-anchor) - var(--rd-gutter-vw)));
  }
  /* Same clamp as .rd-edge-pull, so the logo tracks the list's left edge at
     every width. Unclamped it resolved to a positive margin on narrow screens
     and shoved the logo ~320px into a 768px viewport. */
  .rd-logo-pull { margin-left: min(0px, calc(var(--rd-anchor) - var(--rd-gutter-vw))); }
}

/* Backstop against sideways scrolling. The decorative grids below are capped so
   they shouldn't overflow, but sub-pixel rounding on percentage bleeds is
   enough to raise a scrollbar, and a phone that scrolls sideways feels broken.
   On <html>, not <body>: body's overflow is propagated to the viewport and then
   does nothing. `clip` rather than `hidden` so no scroll container is created
   and the sticky header keeps sticking. */
html { overflow-x: clip; }

:root {
  --accent: #E24D66;
  --accent-border: #FA7D92;
  --card: #171A22;
  --card-border: #232731;
  --feature-border: #33394B;
  --splash-black: #0C0F14;
  --text-body: #D3DBEF;
  --text-subtle: #8890A5;
  --text-head: #FFFFFF;
}

/* Smooth anchor jumps for the article's in-page links */
html { scroll-behavior: smooth; }

/* Decorative grid pattern, top-left corner only (copied from the mockup:
   118px square cells, faint card-coloured lines, fading out to bottom-right).
   z-index:-1 keeps it behind the page content but above the page background. */
body { position: relative; }
.bg-grid {
  position: absolute;
  top: 0;
  /* Anchor a vertical grid line on the content column's left edge: the content
     starts at --rd-gutter, so subtract one 118px cell to put the grid's own
     left edge exactly one cell before it and land a line on the content edge.
     Clamped at 0 so on very wide screens it hugs the corner instead of
     drifting inward. */
  left: min(0px, calc(var(--rd-gutter) - 118px));
  /* Capped so it can't push the page wider than the viewport on a phone; it
     just shows fewer cells. Same for the reviews/footer grids below. */
  width: min(620px, 100%);
  height: 680px;
  z-index: 0;
  pointer-events: none;
  background-image:
    linear-gradient(to right, #16191E 1px, transparent 1px),
    linear-gradient(to bottom, #16191E 1px, transparent 1px);
  background-size: 118px 118px;
  /* Hold the grid fully opaque further out from the corner (solid to 28%) and
     push the fade-out point outward (transparent at 78%) so more of the grid is
     visible before it dissolves. */
  -webkit-mask-image: radial-gradient(125% 125% at top left, #000 0%, #000 28%, transparent 78%);
          mask-image: radial-gradient(125% 125% at top left, #000 0%, #000 28%, transparent 78%);
}

/* ---------------------------------------------------------------------------
   Larger grid behind the Latest Reviews block — top-left, fading down-right
   (same 118px cells as the hero grid). Sits behind the cards (z-index:-1) so it
   only shows through the gaps and surrounding margin. */
.rd-reviews { position: relative; }
.rd-reviews::before {
  content: "";
  position: absolute;
  /* Flush with the top of the dark band (the page-selector's midpoint), 77px
     above the reviews wrapper — same offset the dark band itself uses. */
  top: -77px;
  /* Reach the page's left edge (x=0) so the grid is flush and shares the hero
     grid's line phase. The section sits at the logo line; cancel that offset. */
  left: calc(var(--rd-gutter-vw) * -1 - min(0px, calc(var(--rd-anchor) - var(--rd-gutter-vw))));
  /* This pseudo's containing block is the content column, not the page, and it
     starts at the page's left edge — so the page width is the column plus one
     inset on each side. (100vw would overshoot by the scrollbar.) */
  width: min(760px, calc(100% + 2 * var(--rd-inset)));
  height: 460px;
  z-index: -1;
  pointer-events: none;
  background-image:
    linear-gradient(to right, #16191E 1px, transparent 1px),
    linear-gradient(to bottom, #16191E 1px, transparent 1px);
  background-size: 118px 118px;
  -webkit-mask-image: radial-gradient(120% 120% at top left, #000 0%, #000 25%, transparent 75%);
          mask-image: radial-gradient(120% 120% at top left, #000 0%, #000 25%, transparent 75%);
}

/* ---------------------------------------------------------------------------
   Dark lower-page background (#0C0F14): a full-bleed band that begins at the
   page-selector's vertical midpoint (77px above the reviews wrapper = the 48px
   gap + half the 58px bar) and runs down to the footer boundary. It sits behind
   the section content (z-index:-1) but in front of the page bg.

   It stops at --rd-footer-overlap above its own bottom edge — exactly where the
   footer's backdrop takes over. Running past that point would paint solid
   #0C0F14 over the footer's grid, because <main> now sits above the footer in
   the stacking order (see .rd-footer-grid below).
--------------------------------------------------------------------------- */
.rd-dark { position: relative; }
.rd-dark::before {
  content: "";
  position: absolute;
  z-index: -1;
  top: -77px;
  bottom: var(--rd-footer-overlap);
  /* Bleed to the page edges using % of the wrapper width (which excludes the
     scrollbar), so it lands exactly at x=0 / x=clientWidth with no overflow. */
  left: calc(var(--rd-bleed) * -1);
  right: calc(var(--rd-bleed) * -1);
  background: #0C0F14;
}

/* ---------------------------------------------------------------------------
   Footer backdrop + grid.

   The lower dark area starts partway UP the info box rather than below it, so
   the box's bottom edge overlaps the footer's background instead of clearing
   it. --rd-footer-overlap is how far above the info box's bottom that boundary
   sits; --rd-footer-rise is the same boundary measured from the footer's own
   top edge (the overlap plus <main>'s 48px pb-12 and the footer's 48px mt-12).

   For the box to sit ON TOP of the grid, <main> (z-10) has to win over the
   footer, so the footer drops to z-0 — see the `z-0` class in inc/footer.php.
   That means the footer can no longer rely on .rd-dark bleeding down into it,
   hence the ::after backdrop below.
--------------------------------------------------------------------------- */
:root {
  --rd-footer-overlap: 40px;
  --rd-footer-rise: 136px; /* 40 overlap + 48 main pb-12 + 48 footer mt-12 */
}

.rd-footer-grid { position: relative; }

/* Solid dark backdrop, extended up past the footer's top edge to the boundary.
   Unmasked, so it stays opaque where the grid above it fades out. */
.rd-footer-grid::after {
  content: "";
  position: absolute;
  z-index: -1;
  top: calc(var(--rd-footer-rise) * -1);
  bottom: 0;
  left: 0;
  right: 0;
  background: #0C0F14;
  pointer-events: none;
}

/* Decorative grid pattern — same 118px cells / line colour as the hero +
   reviews grids, anchored to the content column's left edge and fading out
   toward the bottom-right. Sits above the backdrop (z-0 vs -1) but below the
   footer content (which is z-10). */
.rd-footer-grid::before {
  content: "";
  position: absolute;
  top: calc(var(--rd-footer-rise) * -1);
  height: calc(100% + var(--rd-footer-rise));
  left: min(0px, calc(var(--rd-gutter) - 118px));
  width: min(720px, 100%);
  z-index: 0;
  pointer-events: none;
  background-image:
    linear-gradient(to right, #16191E 1px, transparent 1px),
    linear-gradient(to bottom, #16191E 1px, transparent 1px);
  background-size: 118px 118px;
  -webkit-mask-image: radial-gradient(120% 130% at top left, #000 0%, #000 30%, transparent 80%);
          mask-image: radial-gradient(120% 130% at top left, #000 0%, #000 30%, transparent 80%);
}

/* ---------------------------------------------------------------------------
   Full-bleed band behind the SEO info container, in the page colour (#11141A) —
   the same background the server list sits on up top. This lifts the area out
   of the darker lower band (#0C0F14) so the info box shares the servers' bg.
   Full-bleed to the page edges using the same %-maths as .rd-dark.

   It ends --rd-footer-overlap ABOVE the info box's bottom edge, so the box's
   last stretch sits over the darker footer background + grid rather than on its
   own lighter band. */
.rd-article-band { position: relative; }
.rd-article-band::before {
  content: "";
  position: absolute;
  z-index: -1;
  top: -44px;
  bottom: var(--rd-footer-overlap);
  left: calc(var(--rd-bleed) * -1);
  right: calc(var(--rd-bleed) * -1);
  background: #11141A;
}

/* ---------------------------------------------------------------------------
   Fluid hero typography. The layout width is a percentage (see --rd-gutter),
   so the hero text must scale with the viewport too, or it looks proportionally
   small on wide screens. Each `calc(<a>vw + <b>px)` is a linear fluid size that
   equals the 1440px design value at 1440px and grows ~1.2x by 2560px (clamped
   so it's flat below 1440 and above 2560). This lifts the hero block from
   ~201px (scaled to 1440) toward the design's 237px on a 2560px screen.
--------------------------------------------------------------------------- */
.rd-hero {
  padding-top: clamp(32px, calc(0.5143vw + 24.59px), 37.76px);
  padding-bottom: clamp(32px, calc(0.5143vw + 24.59px), 37.76px);
}
.rd-hero-title { font-size: clamp(36px, calc(0.5786vw + 27.67px), 42.48px); }
.rd-hero-para {
  font-size: clamp(19px, calc(0.3054vw + 14.6px), 22.42px);
  max-width: clamp(655px, calc(10.527vw + 503.4px), 772.9px);
}
.rd-tag-label { font-size: clamp(19px, calc(0.31vw + 14.54px), 22.48px); }
.rd-tag-chip {
  font-size: clamp(16px, calc(0.257vw + 12.3px), 18.88px);
  padding: clamp(7px, calc(0.1125vw + 5.38px), 8.26px) clamp(14px, calc(0.225vw + 10.76px), 16.52px);
}

/* ---------------------------------------------------------------------------
   Bottom SEO article ($txt['bottom_seo_article']['index'])
   The content (headings, paragraphs, lists, links) is preserved verbatim for
   SEO; we just restyle it to the new theme and hide the old Semantic ToC
   accordion (the new design omits it).
--------------------------------------------------------------------------- */
.rd-article { color: var(--text-body); font-size: 15px; line-height: 1.7; }

/* Neutralise the article's own Semantic "inverted segment" wrapper so it sits
   flat inside our Feature-BG panel. */
.rd-article .ui.inverted.segment,
.rd-article .ui.segment {
  background: transparent !important;
  border: 0 !important;
  box-shadow: none !important;
  margin: 0 !important;
  padding: 0 !important;
}

/* Hide the old Table-of-Contents accordion (not in the new design). */
.rd-article .ui.accordion { display: none !important; }

.rd-article h2 {
  color: var(--text-head);
  font-weight: 800;
  font-size: 1.5rem;
  line-height: 1.25;
  margin: 1.75rem 0 0.75rem;
}
.rd-article h2:first-child { margin-top: 0; }
.rd-article h3 {
  color: var(--text-head);
  font-weight: 700;
  font-size: 1.2rem;
  margin: 1.25rem 0 0.5rem;
}
.rd-article p { margin: 0 0 0.9rem; }
.rd-article strong { color: var(--text-head); font-weight: 700; }

.rd-article ul,
.rd-article ol { margin: 0 0 1rem; padding-left: 1.25rem; }
.rd-article ul { list-style: disc; }
.rd-article ol { list-style: decimal; }
.rd-article li { margin: 0.35rem 0; }

.rd-article a {
  color: var(--accent);
  text-decoration: none;
  font-weight: 600;
}
.rd-article a:hover { text-decoration: underline; }

.rd-article img {
  border-radius: 6px;
  max-width: 320px;
  height: auto;
  margin: 0.5rem 0 1rem;
  display: block;
}
@media (min-width: 768px) {
  .rd-article img { float: right; margin: 0.25rem 0 1rem 1.75rem; }
}

/* Copy-IP "copied" state */
.copy-btn.is-copied { background-color: var(--accent); }

/* ---------------------------------------------------------------------------
   Go-to-page popover, opened from the "…" gap in the pagination bar.
   Written as plain CSS on the design tokens rather than Tailwind utilities,
   because the markup is built in JS at runtime — a compiled Tailwind build
   (see README TODO 1) only scans the source files, so utility classes created
   in script would be purged.
--------------------------------------------------------------------------- */
.rd-pg-jump { cursor: pointer; background: none; border: 0; font: inherit; line-height: inherit; }

.rd-pg-pop {
  position: fixed;
  z-index: 60;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px;
  background: var(--card);
  border: 1px solid var(--card-border);
  border-radius: 6px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, .55);
}
.rd-pg-pop input {
  width: 7em;
  height: 38px;
  padding: 0 10px;
  background: var(--splash-black);
  border: 1px solid var(--feature-border);
  border-radius: 4px;
  color: var(--text-head);
  font: inherit;
  font-size: 16px;
  /* Hide the number spinners — they crowd a field this narrow. */
  -moz-appearance: textfield;
}
.rd-pg-pop input::-webkit-outer-spin-button,
.rd-pg-pop input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.rd-pg-pop input::placeholder { color: var(--text-subtle); }
.rd-pg-pop input:focus { outline: 0; border-color: var(--accent); }
.rd-pg-pop.is-invalid input { border-color: var(--accent); background: rgba(226, 77, 102, .12); }

.rd-pg-pop button {
  height: 38px;
  padding: 0 16px;
  background: var(--accent);
  border: 0;
  border-radius: 4px;
  color: #fff;
  font: inherit;
  font-size: 15px;
  font-weight: 700;
  cursor: pointer;
  transition: background-color .15s;
}
.rd-pg-pop button:hover { background: var(--accent-border); }

/* ===========================================================================
   SUB-PAGES (blog + tools)
   =========================================================================== */

/* ---------------------------------------------------------------------------
   Blog article body (.rd-prose)

   The stored article_body is real HTML written for the old theme: <p
   class="blog_p">, <h2>, <a>, plus its own inline <style> block. blog-post.php
   strips that <style> (it set h2{color:red} un-scoped, which repainted every
   heading on the page) and these rules take over. Same shape as .rd-article
   above, tuned for long-form reading rather than an SEO footer.
--------------------------------------------------------------------------- */
.rd-prose { color: var(--text-body); font-size: 17px; line-height: 1.75; }

.rd-prose > :first-child { margin-top: 0; }
.rd-prose > :last-child  { margin-bottom: 0; }

.rd-prose p,
.rd-prose .blog_p {
  /* The old theme forced .blog_p to pure white !important, which is too hot for
     body copy on this palette. Match the rest of the page instead. */
  color: var(--text-body) !important;
  margin: 0 0 1.15rem;
}

.rd-prose h2 {
  color: var(--text-head);
  font-weight: 800;
  font-size: 1.65rem;
  line-height: 1.25;
  margin: 2.25rem 0 0.85rem;
  padding-left: 0.75rem;
  border-left: 3px solid var(--accent);
}
.rd-prose h3 {
  color: var(--text-head);
  font-weight: 700;
  font-size: 1.3rem;
  margin: 1.75rem 0 0.6rem;
}
.rd-prose h4 { color: var(--text-head); font-weight: 700; font-size: 1.1rem; margin: 1.4rem 0 0.5rem; }

.rd-prose strong { color: var(--text-head); font-weight: 700; }
.rd-prose em     { font-style: italic; }

.rd-prose ul, .rd-prose ol { margin: 0 0 1.15rem; padding-left: 1.35rem; }
.rd-prose ul { list-style: disc; }
.rd-prose ol { list-style: decimal; }
.rd-prose li { margin: 0.4rem 0; }
.rd-prose li::marker { color: var(--text-subtle); }

.rd-prose a { color: var(--accent); text-decoration: none; font-weight: 600; }
.rd-prose a:hover { text-decoration: underline; }

.rd-prose img {
  border-radius: 6px;
  max-width: 100%;
  height: auto;
  margin: 1.25rem 0;
  display: block;
  border: 1px solid var(--card-border);
}

.rd-prose blockquote {
  margin: 1.5rem 0;
  padding: 0.75rem 0 0.75rem 1.15rem;
  border-left: 3px solid var(--feature-border);
  color: var(--text-subtle);
  font-style: italic;
}

.rd-prose code {
  background: var(--splash-black);
  border: 1px solid var(--card-border);
  border-radius: 4px;
  padding: 0.1em 0.4em;
  font-size: 0.9em;
  color: var(--text-head);
}
.rd-prose pre {
  background: var(--splash-black);
  border: 1px solid var(--card-border);
  border-radius: 6px;
  padding: 1rem;
  overflow-x: auto;
  margin: 0 0 1.15rem;
}
.rd-prose pre code { background: none; border: 0; padding: 0; }

.rd-prose hr { border: 0; border-top: 1px solid var(--card-border); margin: 2rem 0; }

/* Wide content must scroll inside its own box, never the page. */
.rd-prose table { display: block; overflow-x: auto; width: 100%; margin: 0 0 1.15rem; }
.rd-prose th, .rd-prose td { border: 1px solid var(--card-border); padding: 0.5rem 0.75rem; text-align: left; }
.rd-prose th { color: var(--text-head); background: var(--splash-black); font-weight: 700; }

/* ---------------------------------------------------------------------------
   Server-side status messages.

   validate() (engine/security.php) writes its success/error output as Semantic
   markup — a "ui success message" div — straight into the session, and the tool
   forms echo it back via uniSession(). Restyling it here means the engine does
   not have to change.
--------------------------------------------------------------------------- */
.rd-msg .ui.message {
  position: relative;
  display: block;
  margin: 0 0 1rem;
  padding: 1rem 2.5rem 1rem 1rem;
  border-radius: 6px;
  border: 1px solid var(--card-border);
  background: var(--card);
  color: var(--text-body);
  font-size: 15px;
  line-height: 1.6;
}
.rd-msg .ui.message .header { display: block; color: var(--text-head); font-weight: 700; margin-bottom: 0.2rem; }
.rd-msg .ui.message p { margin: 0; }
.rd-msg .ui.success.message { border-color: var(--splash-green); background: rgba(70, 223, 49, .08); }
.rd-msg .ui.success.message .header { color: var(--splash-green); }
.rd-msg .ui.error.message,
.rd-msg .ui.negative.message { border-color: var(--accent); background: rgba(226, 77, 102, .10); }
.rd-msg .ui.error.message .header,
.rd-msg .ui.negative.message .header { color: var(--accent-border); }

/* The engine ships a Semantic "close icon" <i> inside these messages; without
   Semantic's stylesheet it renders as a stray empty element. app.js wires it up
   as a real dismiss button, so give it a hit area and a glyph. */
.rd-msg .ui.message > i.close.icon {
  position: absolute;
  top: 0.55rem;
  right: 0.55rem;
  width: 28px;
  height: 28px;
  line-height: 28px;
  text-align: center;
  cursor: pointer;
  border-radius: 4px;
  color: var(--text-subtle);
  font-style: normal;
}
.rd-msg .ui.message > i.close.icon::before { content: "\00d7"; font-size: 20px; }
.rd-msg .ui.message > i.close.icon:hover { color: var(--text-head); background: rgba(255, 255, 255, .06); }

/* ---------------------------------------------------------------------------
   Tool pages

   The three big tools (RGB generator, banner maker, symbols) ship their own
   scripts, which build DOM at runtime using their own Tailwind token names
   (bg-accent, bg-container-light, text-muted, ...). Each tool page remaps those
   names onto the brand hexes via $rd_meta['tw_colors'], so the generated markup
   lands on-brand without touching the scripts. What is left here is the handful
   of plain-CSS bits those scripts assume.
--------------------------------------------------------------------------- */

/* Native form controls, for the tool pages that use plain markup (status
   checker, votifier tester, formatting, RGB generator). Element rules rather
   than utilities because several of these controls are rendered by the tool
   scripts, where utility classes would be purged by a compiled Tailwind build
   (README TODO 1).

   OPT-IN, via .rd-form on a wrapper. The symbols and banner-maker tools style
   every one of their controls with utility classes already; an element rule
   here out-specifies those (0,1,1 beats 0,1,0) and would stretch their inline
   selects and hex fields to full width. So those two pages carry .rd-tool as a
   page marker but deliberately NOT .rd-form. */
.rd-form input[type="text"],
.rd-form input[type="number"],
.rd-form input[type="search"],
.rd-form input[type="password"],
.rd-form textarea,
.rd-form select {
  width: 100%;
  background: var(--splash-black);
  border: 1px solid var(--feature-border);
  border-radius: 4px;
  color: var(--text-head);
  font: inherit;
  font-size: 16px;             /* 16px stops iOS zooming the page on focus */
  padding: 10px 12px;
  min-height: 44px;
  transition: border-color .15s, background-color .15s;
}
.rd-form textarea { min-height: 110px; resize: vertical; line-height: 1.5; }
.rd-form input::placeholder,
.rd-form textarea::placeholder { color: var(--text-subtle); }
.rd-form input:focus,
.rd-form textarea:focus,
.rd-form select:focus { outline: 0; border-color: var(--accent); }
.rd-form input[type="color"] { padding: 4px; min-height: 44px; cursor: pointer; }

/* Range slider (symbols page scale control) */
.rd-form input[type="range"] {
  width: 100%;
  min-height: 0;
  padding: 0;
  background: transparent;
  border: 0;
  accent-color: var(--accent);
}

/* Monospace output blocks — the generators write their result into these. */
.rd-form pre,
.rd-form .rd-out {
  background: var(--splash-black);
  border: 1px solid var(--feature-border);
  border-radius: 6px;
  padding: 14px 16px;
  color: var(--text-head);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 15px;
  line-height: 1.6;
  overflow-x: auto;
  white-space: pre-wrap;
  word-break: break-word;
  cursor: pointer;
  transition: border-color .15s;
}
.rd-form pre:hover,
.rd-form .rd-out:hover { border-color: var(--accent); }

/* The Minecraft preview surfaces (RGB output, banner canvas backdrop) sit on
   the darkest tone so the generated colours read true. */
.rd-tool-preview {
  background: var(--splash-black);
  border: 1px solid var(--feature-border);
  border-radius: 6px;
}

/* NOTE: no generic #toast rule here on purpose. The symbols and banner-maker
   pages each style their own #toast with utility classes and animate it by
   toggling classes (.hidden, .toast-enter/-visible/-exit). An id selector would
   out-specify those class rules and freeze the animation, so the toast is left
   entirely to the page that owns it. */

/* jscolor's picker (RGB generator) renders outside our containers. */
.jscolor-picker-wrap { z-index: 80 !important; }

/* ---------------------------------------------------------------------------
   Playwire ad slots
   ---------------------------------------------------------------------------
   Markup comes from rd_ad() in inc/helpers.php. RAMP injects an iframe into
   the desk/mobi div and sizes it itself, so nothing here sets a fixed height -
   only the reserved minimum that stops the page jumping when a unit fills.

   The leaderboard sits under the page header, matching where the old theme
   put it. The 20px floor and 150px cap are carried over from the old inline
   style verbatim. Note the floor always applies: the wrapper holds the two
   data-pw divs and a script, so it is never :empty even before a unit fills.
   20px is small enough that an unfilled slot is not a visible gap. */
.rd-ad-leaderboard {
  margin: 0 0 1.5rem;
  min-height: 20px;
  max-height: 150px;
  overflow: hidden;
  text-align: center;
}

/* The side rails live in the wide gutter that --rd-gutter opens up at 1920
   (18.5%, ~355px each side at that width). Below 1920 the gutter is far too
   narrow - 8% at 1536 is ~123px - so the rails would sit on top of the
   content. They are display:none until there is genuinely room for them.

   position: sticky keeps a rail in view down a long article without needing
   scroll handlers. top clears the 80px sticky header plus a little breathing
   room. */
.rd-ad-rail { display: none; }

@media (min-width: 1920px) {
  .rd-ad-rail {
    display: block;
    position: fixed;
    top: 6rem;
    width: 300px;
    max-width: calc(var(--rd-gutter-vw) - 2rem);
    z-index: 30;
  }
  /* Centre each rail inside its gutter: half the gutter, less half the rail. */
  .rd-ad-rail-left  { left:  calc((var(--rd-gutter-vw) - 300px) / 2); }
  .rd-ad-rail-right { right: calc((var(--rd-gutter-vw) - 300px) / 2); }
}
