/* dzsm.app — informational site (TODO-2 F1).
 *
 * Tokens are copied from webui/src/index.css so the site and the panel read as
 * one product. Keep them in sync by hand.
 *
 * Plain CSS on purpose — no preprocessor, no CSS modules, no hashing. The build
 * copies this file to out/styles.css verbatim, so what you read here is what
 * ships. Class names come from the markup in src/sections/. */

:root {
  --bg: #14161b;
  --bg-raised: #1b1e25;
  --bg-hover: #242832;
  --border: #2c303a;
  --text: #d7d9e0;
  --text-muted: #8b8fa3;
  --text-heading: #f4f5f7;
  --accent: #5b8cff;
  --accent-hover: #7aa0ff;
  --good: #3fbf6f;
  --warning: #e0a72e;
  --danger: #e5484d;
  --on-accent: #0b0d12;
  --shadow: rgba(0, 0, 0, 0.35);
  --sans: system-ui, "Segoe UI", Roboto, sans-serif;
  --mono: ui-monospace, Consolas, monospace;
  --wrap: 940px;
  /* Higher than the app's 0.03. There the badge reads because it sits behind
     cards and shows through the gutters between them; this page is mostly flat
     background, where 0.03 computes to #1a1c21 against #14161b and is invisible.
     This is the knob — turn it down if it competes with the text. */
  --watermark-opacity: 0.07;
}

*, *::before, *::after { box-sizing: border-box; }

/* The background lives on :root, NOT on body — same arrangement as the app, and
 * for the same reason: the watermark below sits at z-index -1, so any element
 * background painted between it and the canvas hides it. This is the line that
 * makes body::before visible at all. */
html {
  background: var(--bg);
}

body {
  margin: 0;
  color: var(--text);
  font: 16px/1.65 var(--sans);
  -webkit-font-smoothing: antialiased;
}

/* Page watermark — static/dzsm-badge.svg, copied from webui/public/ and painted
 * through a MASK rather than set as a background-image: the artwork is one black
 * path, so a plain background would be a black smudge on a dark page and unable
 * to follow --text. The mask takes only its alpha; the colour is ours.
 * Adapted from .content::before in webui/src/index.css — same mask, same token,
 * different SIZE. The app's `max(50vw, 100vw)` resolves to 100vw, which in a
 * full-viewport box renders the square badge 1920px tall on a 1080px screen:
 * you get a giant crop of it rather than the mark. Sized to fit the viewport
 * instead, so the whole badge is what shows. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: var(--watermark-opacity);
  background: var(--text);

  -webkit-mask: url("/dzsm-badge.svg") center 20% / min(760px, 78vmin) no-repeat;
  mask: url("/dzsm-badge.svg") center 20% / min(760px, 78vmin) no-repeat;
}

.wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 20px; }

h1, h2, h3, h4 { color: var(--text-heading); line-height: 1.25; }
h1 { font-size: clamp(30px, 5vw, 46px); margin: 0 0 18px; letter-spacing: -0.02em; }
h2 { font-size: 27px; margin: 0 0 10px; letter-spacing: -0.01em; }
h3 { font-size: 19px; margin: 34px 0 10px; }
h4 { font-size: 16px; margin: 0 0 6px; }

a { color: var(--accent); text-decoration: none; }
a:hover { color: var(--accent-hover); text-decoration: underline; }

code {
  font-family: var(--mono);
  font-size: 0.9em;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 1px 5px;
}

/* ---------------------------------------------------------------- hero -- */

/* The gradient alone, with no `var(--bg)` layer under it: an opaque background
 * here would hide the body::before watermark, which is centred at 25% and
 * therefore lands exactly behind this block on the home page. */
.hero {
  padding: 40px 0 52px;
  background:
    radial-gradient(1100px 380px at 50% -140px, rgba(91, 140, 255, 0.13), transparent 70%);
  border-bottom: 1px solid var(--border);
}

.hero-logo {
  display: block;
  width: 192px;
  height: auto;
  margin: 0 auto 22px;
  filter: drop-shadow(0 6px 22px rgba(0, 0, 0, 0.5));
}

.eyebrow {
  margin: 0 0 14px;
  color: var(--text-muted);
  font-size: 13px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.lede { font-size: 18px; max-width: 68ch; color: var(--text); margin: 0 0 26px; }

.cmd {
  background: #0e1015;
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: 8px;
  padding: 14px 16px;
  margin: 0 0 10px;
  overflow-x: auto;
  box-shadow: 0 2px 10px var(--shadow);
}
.cmd code {
  background: none;
  border: none;
  padding: 0;
  font-size: 14px;
  color: var(--text-heading);
  white-space: pre;
}

.fineprint { color: var(--text-muted); font-size: 13.5px; margin: 8px 0 0; }

/* Branch coming-soon: the only page (sections/ComingSoon.jsx). One centred
   block filling the window; there is no menu above it and no footer below. */
.hero.soon { min-height: 100vh; display: flex; align-items: center; text-align: center; border-bottom: none; }
.hero.soon .wrap { width: 100%; }
.hero.soon .lede { margin: 0 auto; }

/* -------------------------------------------------------------- tabbar -- */

.tabbar {
  position: sticky;
  top: 0;
  z-index: 5;
  background: rgba(20, 22, 27, 0.92);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--border);
}
.tabbar .wrap { display: flex; gap: 26px; overflow-x: auto; align-items: center; }
.tabbar a {
  padding: 13px 0;
  color: var(--text-muted);
  font-size: 14.5px;
  white-space: nowrap;
  border-bottom: 2px solid transparent;
}
.tabbar a:hover { color: var(--text-heading); border-bottom-color: var(--accent); text-decoration: none; }

/* The brand is the home link. Every page has the menu, so this is the only way
 * back to `/` from a sub-page. */
.tabbar .brand {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--text-heading);
  font-weight: 700;
  letter-spacing: -0.01em;
  font-size: 16px;
  margin-right: 4px;
  border-bottom-color: transparent;
}
.tabbar .brand img { width: 26px; height: 26px; display: block; }
.tabbar .brand:hover { border-bottom-color: transparent; }
/* Marks the page you are on. Paired with aria-current="page" in Nav.jsx —
 * colour alone does not tell a screen reader anything. */
.tabbar a.current {
  color: var(--text-heading);
  border-bottom-color: var(--accent);
}

/* Language switcher. Sits in the tabbar, pushed right, and is not rendered at
 * all while LANGUAGES has a single entry (src/sections/Nav.jsx). */
.langswitch { display: flex; gap: 14px; margin-left: auto; padding-left: 26px; }
.langswitch a { font-size: 13.5px; }
.langswitch a.current { color: var(--text-heading); border-bottom-color: var(--border); }

/* ------------------------------------------------------------ sections -- */

.section { padding: 56px 20px; border-bottom: 1px solid var(--border); }
.section-lede { color: var(--text-muted); max-width: 72ch; margin: 0 0 8px; }

/* The panel tour (sections/Demo.jsx). The width/height attributes give the box
   its aspect ratio before the poster arrives; these let it shrink with the page. */
.demo-video {
  display: block;
  width: 100%;
  height: auto;
  margin-top: 18px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--bg-raised);
}

/* ------------------------------------------------------------ showcase -- */

/* The feature showcase (sections/Showcase.jsx + showcase.js).
 *
 * Without .is-live — JS off, or before the script runs — it is a two-column
 * gallery with every screenshot and caption visible. That is the no-JS page and
 * it must stay complete. With .is-live the same figures stack into one stage
 * and the script's rail sits beside it.
 *
 * The block is wider than --wrap: a 1440px panel screenshot squeezed into
 * 940px minus a rail is too small to read. It breaks out of the column by
 * negative margin rather than transform, because the page-load stagger animates
 * transform on this element. */
.showcase {
  --showcase-w: min(1200px, 100vw - 40px);
  width: var(--showcase-w);
  margin: 22px 0 0 calc((100% - var(--showcase-w)) / 2);
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 420px), 1fr));
  gap: 28px 24px;
}

.shot { margin: 0; min-width: 0; }

.shot-frame {
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
  background: var(--bg-raised);
  box-shadow: 0 24px 60px -28px var(--shadow);
}
.shot-frame img { display: block; width: 100%; height: auto; }

/* A browser title bar, so the picture reads as the panel in a browser rather
 * than a poster. The path is the panel's real URL for that page. */
.shot-chrome {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 8px 12px;
  border-bottom: 1px solid var(--border);
  background: var(--bg);
}
.shot-chrome .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--border); }
.shot-chrome .dot:nth-child(1) { background: var(--danger); }
.shot-chrome .dot:nth-child(2) { background: var(--warning); }
.shot-chrome .dot:nth-child(3) { background: var(--good); }
.shot-path {
  margin-left: 8px;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--text-muted);
}

/* Caption and rail button share this layout: number, then label over blurb. */
.shot-caption,
.showcase-view {
  display: grid;
  grid-template-columns: 26px minmax(0, 1fr);
  gap: 10px;
  align-items: start;
}
.shot-caption { padding: 12px 4px 0; }
.shot-num {
  font-family: var(--mono);
  font-size: 12px;
  font-weight: 600;
  color: var(--text-muted);
  padding-top: 2px;
}
.shot-text { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.shot-label { color: var(--text-heading); font-size: 15px; }
.shot-blurb { color: var(--text-muted); font-size: 13.5px; line-height: 1.5; }

/* ---- enhanced: one stage, one rail ---- */

/* The rail sits under the stage, not beside it as on the site this was modelled
 * on: the screenshots are ~2.2:1, so a side rail of twelve entries would stand
 * taller than the picture next to it. */
.showcase.is-live {
  grid-template-columns: minmax(0, 1fr);
  gap: 18px;
}
.showcase.is-live .shot { grid-area: 1 / 1; display: none; }
.showcase.is-live .shot.is-active { display: block; }

.showcase-rail {
  grid-area: 2 / 1;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(175px, 1fr));
  gap: 6px;
}
.showcase-view {
  width: 100%;
  padding: 9px 10px;
  text-align: left;
  font: inherit;
  color: inherit;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 8px;
  cursor: pointer;
  transition: background 0.2s ease, border-color 0.2s ease;
}
.showcase-view:hover { background: var(--bg-hover); }
.showcase-view:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.showcase-view.is-active {
  background: rgba(91, 140, 255, 0.09);
  border-color: rgba(91, 140, 255, 0.45);
}
.showcase-view.is-active .shot-num,
.showcase-view.is-active .shot-label { color: var(--accent-hover); }
.showcase-view .shot-label { font-size: 14px; }
/* The active figure's own caption, under the stage, carries the blurb. */
.showcase-view .shot-blurb { display: none; }

@media (prefers-reduced-motion: no-preference) {
  .showcase.is-live .shot.is-active { animation: shot-in 220ms ease both; }
}
@keyframes shot-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

.aside {
  color: var(--text-muted);
  font-size: 14.5px;
  border-left: 2px solid var(--border);
  padding-left: 14px;
  margin-top: 28px;
}

/* -------------------------------------------------------------- tables -- */

.table-wrap { overflow-x: auto; margin: 20px 0; }

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 14.5px;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
}
caption {
  caption-side: bottom;
  text-align: left;
  color: var(--text-muted);
  font-size: 13px;
  padding: 10px 2px 0;
}
th, td { padding: 11px 13px; text-align: left; border-bottom: 1px solid var(--border); vertical-align: top; }
thead th {
  background: var(--bg-hover);
  color: var(--text-heading);
  font-size: 12.5px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
tbody tr:last-child td { border-bottom: none; }
.sub { color: var(--text-muted); font-size: 12.5px; }

.row-pick { background: rgba(91, 140, 255, 0.07); }
.row-warn { background: rgba(224, 167, 46, 0.06); }
.row-bad  { background: rgba(229, 72, 77, 0.05); color: var(--text-muted); }

.pill {
  display: inline-block;
  background: var(--accent);
  color: var(--on-accent);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 2px 7px;
  border-radius: 999px;
  vertical-align: middle;
}

/* /servers/ (plans/57 D). The address is the one cell a reader copies, so one
   click selects all of it: user-select, not a copy button, because the page has
   no script. Counts and times stay on one line. */
table.servers code.copy { user-select: all; white-space: nowrap; }
table.servers td.num { white-space: nowrap; }
/* A name is the column people read; without a floor it wraps word by word
   while the address column holds its width. */
table.servers td:first-child { min-width: 16ch; }

td.yes { color: var(--good); }
td.no  { color: var(--danger); }

/* ------------------------------------------------------------ callouts -- */

.callout {
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 20px 22px;
  margin: 26px 0;
}
.callout h3 { margin-top: 0; }
.callout p:last-child, .callout ul:last-child { margin-bottom: 0; }
.callout-accent { border-color: rgba(91, 140, 255, 0.45); }
.callout-warn   { border-color: rgba(224, 167, 46, 0.45); }
/* Reserved for the one mistake on this page that cannot be undone after you
 * have paid — currently the Arm64 warning. Keep it rare or it stops reading as
 * different from callout-warn. */
.callout-danger { border-color: rgba(229, 72, 77, 0.5); background: rgba(229, 72, 77, 0.05); }
.callout-danger h3 { color: var(--danger); }

/* --------------------------------------------------------------- lists -- */

.checks { padding-left: 22px; }
.checks li { margin-bottom: 11px; }
.notes { padding-left: 22px; color: var(--text); }
.notes li { margin-bottom: 10px; }

/* ------------------------------------------------------------ verdicts -- */

.verdict-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 14px;
  margin-top: 22px;
}
.verdict {
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 17px 19px;
}
.verdict p { margin: 0; font-size: 14.5px; color: var(--text-muted); }
.verdict-good { border-color: rgba(63, 191, 111, 0.4); }
.verdict-good h4 { color: var(--good); }

/* --------------------------------------------- cross-page transitions -- */

/* Navigating between the five pages cross-fades instead of flashing white.
 *
 * This is the CSS View Transitions API, and it is the only way to do this that
 * this directory allows: one declaration, no script, no router, no bundle. The
 * pages stay ordinary prerendered HTML reached by ordinary <a href> — the
 * browser does the animation between two real document loads. Anything that
 * offers "smoother" transitions (barba, swup, an SPA router) does it by
 * hijacking navigation in JavaScript, which is the thing the no-framework rule
 * exists to prevent.
 *
 * Chromium and Safari animate; Firefox navigates normally and sees the fallback
 * below. Nothing is conditional on it working — there is no state, no fade-in
 * that could get stuck, and no element hidden waiting to be revealed. Turn the
 * whole block off and the site behaves exactly as it did before. */
@view-transition {
  navigation: auto;
}

/* The menu is identical and in the same place on every page, so it is captured
 * as its own group and simply stays put while the content under it changes.
 * Without this it would cross-fade with everything else — a menu that blinks on
 * every click, which reads as a page flash rather than a transition. */
.tabbar {
  view-transition-name: site-nav;
}

/* Explicit opacity animations rather than the default: the default group also
 * animates width and height, and these pages differ in length by a factor of
 * six, so the outgoing snapshot would visibly scale.
 *
 * A plain fade, with no movement — the per-block stagger below supplies that,
 * and doing it here as well slid the whole page while its contents were
 * separately sliding inside it. The old page leaves quickly so the incoming
 * one is not animating behind a stale copy of itself. */
::view-transition-old(root) {
  animation: vt-out 90ms linear both;
}
::view-transition-new(root) {
  animation: vt-fade 150ms linear both;
}

@keyframes vt-out {
  to { opacity: 0; }
}
@keyframes vt-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* The arrival, staggered.
 *
 * A whole-page cross-fade between two dark pages is nearly invisible — the
 * pixels barely differ. What reads as a transition is the content assembling:
 * each block rises and fades in just behind the one above it. This runs on
 * every page load, so it is also the transition in browsers that do not support
 * view transitions at all, which is why it is not inside an @supports.
 *
 * Blocks are the direct children of the page's <section> (and of the hero's
 * inner .wrap): headings, ledes, callouts, tables, disclosures. Cheap to
 * animate — opacity and transform only, no layout. */
@media (prefers-reduced-motion: no-preference) {
  .section > *,
  .hero > .wrap > * {
    animation: block-in 360ms cubic-bezier(0.2, 0.6, 0.3, 1) both;
  }

  /* Hand-written rather than a per-element --i, because that would mean a style
     attribute on every block and the markup should not know about the
     animation. The stagger stops at the 8th: /hosting has fifteen blocks, and
     40ms each would still be fading in two-thirds of a second after you
     arrived. Everything past the 8th shares its delay and comes in together —
     it is below the fold anyway. */
  .section > *:nth-child(1), .hero > .wrap > *:nth-child(1) { animation-delay: 0ms; }
  .section > *:nth-child(2), .hero > .wrap > *:nth-child(2) { animation-delay: 45ms; }
  .section > *:nth-child(3), .hero > .wrap > *:nth-child(3) { animation-delay: 90ms; }
  .section > *:nth-child(4), .hero > .wrap > *:nth-child(4) { animation-delay: 135ms; }
  .section > *:nth-child(5), .hero > .wrap > *:nth-child(5) { animation-delay: 180ms; }
  .section > *:nth-child(6), .hero > .wrap > *:nth-child(6) { animation-delay: 215ms; }
  .section > *:nth-child(7) { animation-delay: 245ms; }
  .section > *:nth-child(n + 8) { animation-delay: 270ms; }

  /* The cards arrive as a group after the heading above them, not with it. */
  .cards > * { animation: block-in 360ms cubic-bezier(0.2, 0.6, 0.3, 1) both; }
  .cards > *:nth-child(1) { animation-delay: 150ms; }
  .cards > *:nth-child(2) { animation-delay: 205ms; }
  .cards > *:nth-child(3) { animation-delay: 260ms; }
  .cards > *:nth-child(4) { animation-delay: 315ms; }
}

@keyframes block-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

/* Motion is a preference, and all of this is decoration. Covers the stagger as
 * well as the view transition — note the stagger sets opacity: 0 in its `from`,
 * so it must be switched off rather than merely shortened. */
@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) {
    animation: none !important;
  }
  .section > *,
  .hero > .wrap > *,
  .cards > * {
    animation: none !important;
  }
}

/* --------------------------------------------------------- home cards -- */

/* One card per section on the landing page. The whole card is the link, so the
 * click target is the card and not four words inside it. */
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 14px;
  margin-top: 22px;
}
.card {
  display: block;
  position: relative;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 18px 20px 20px;
  color: var(--text);
}
.card:hover {
  border-color: var(--accent);
  background: var(--bg-hover);
  text-decoration: none;
}
.card h3 { margin: 0 0 7px; font-size: 17px; }
.card p { margin: 0; font-size: 14.5px; color: var(--text-muted); }
.card-go {
  position: absolute;
  top: 17px;
  right: 18px;
  color: var(--text-muted);
  font-size: 15px;
}
.card:hover .card-go { color: var(--accent); }

/* -------------------------------------------------------- disclosures -- */

/* <details>/<summary>. Native HTML, works with JS off exactly as with JS on —
 * see the comment in src/sections/Disclosure.jsx for what may and may not be
 * put inside one. */
.disc {
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 10px;
  margin: 14px 0;
}
.disc > summary {
  cursor: pointer;
  padding: 14px 20px;
  color: var(--text-heading);
  font-size: 15.5px;
  font-weight: 600;
  list-style: none;
  position: relative;
  padding-right: 44px;
}
.disc > summary::-webkit-details-marker { display: none; }
/* Own marker, so it is on the right and rotates. The default triangle sits left
 * of the text and cannot be positioned. */
.disc > summary::after {
  content: "+";
  position: absolute;
  right: 20px;
  top: 12px;
  font-size: 19px;
  font-weight: 400;
  color: var(--text-muted);
}
.disc[open] > summary::after { content: "–"; }
.disc > summary:hover { color: var(--accent-hover); }
.disc > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: 10px; }
.disc[open] > summary { border-bottom: 1px solid var(--border); }
.disc-body { padding: 4px 20px 18px; }
.disc-body > p:first-child, .disc-body > ul:first-child { margin-top: 14px; }
.disc-body > p:last-child, .disc-body > ul:last-child { margin-bottom: 0; }
.disc-body .notes { margin: 14px 0 0; }

.disc-warn { border-color: rgba(224, 167, 46, 0.45); }
.disc-warn > summary { color: var(--warning); }

/* ---------------------------------------------------------- calculator -- */

/* Every element below is created by calculator.js and exists only when JS runs.
 * Nothing here styles prerendered markup, so with JS off there is no empty box
 * and no gap where the controls would be — the page is what it was.
 *
 * .calc-hit must NOT look like .row-pick. `pick` means "this is the plan we
 * recommend" and is on modded40 permanently; `calc-hit` means "this is the row
 * you just asked for" and moves. They can land on the same row at once, so the
 * hit reads as a green edge rather than another background tint. */

.calc {
  background: var(--bg-raised);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 18px 20px 20px;
  margin: 22px 0;
}
.calc h3 { margin: 0 0 12px; font-size: 17px; }

.calc-controls { display: flex; flex-wrap: wrap; gap: 16px; }
.calc-field { display: flex; flex-direction: column; gap: 5px; }
.calc-field label {
  color: var(--text-muted);
  font-size: 12.5px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.calc select {
  font: inherit;
  font-size: 14.5px;
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 7px 10px;
  min-width: 190px;
}
.calc select:hover { border-color: var(--accent); }
.calc select:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.calc-answer { margin: 16px 0 0; font-size: 15.5px; }
.calc-answer strong { color: var(--text-heading); }
.calc-rented { color: var(--text-muted); }

tr.calc-hit { background: rgba(63, 191, 111, 0.09); }
tr.calc-hit td { color: var(--text-heading); }
tr.calc-hit td:first-child { box-shadow: inset 3px 0 0 var(--good); }

/* ---------------------------------------------------------- blockquote -- */

blockquote {
  margin: 26px 0;
  padding: 18px 22px;
  background: var(--bg-raised);
  border-left: 3px solid var(--warning);
  border-radius: 0 8px 8px 0;
}
blockquote p { margin: 0 0 8px; font-style: italic; }
cite { color: var(--text-muted); font-size: 13.5px; font-style: normal; }

/* -------------------------------------------------------------- footer -- */

footer { padding: 36px 20px 56px; color: var(--text-muted); }
footer p { margin: 0 0 8px; font-size: 14.5px; }

@media (max-width: 600px) {
  .hero { padding: 46px 0 38px; }
  .section { padding: 40px 20px; }
}
