/* forebitcoin.com in the design language, Links Heritage (docs/design/), light or dark as the phone or computer is
   (D30). Its colours, sizes and spaces are the app's (app/src/theme.ts), and its fonts and crest are the site's own,
   which scripts/site-assets.py makes. scripts/site-pages.py makes every page. */

@font-face {
  font-family: "Cinzel";
  src: url("/fonts/cinzel-semibold.woff") format("woff");
  font-weight: 600;
  font-display: swap;
}
@font-face {
  font-family: "Alegreya Sans";
  src: url("/fonts/alegreya-sans-regular.woff") format("woff");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Alegreya Sans";
  src: url("/fonts/alegreya-sans-medium.woff") format("woff");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Alegreya Sans";
  src: url("/fonts/alegreya-sans-italic.woff") format("woff");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

:root {
  --ground: #FFFFFF;
  /* The soft fill of a button that isn't the main one (D60). */
  --surface: #F1F2EE;
  --ink: #0E1F3D;
  --on-ink: #FFFFFF;
  --muted: #5C6370;
  /* Labels, the double rule and the notice's border, and nothing else (D33). */
  --brass: #8A6A2B;
  --hairline: #E4E6EA;
  --gutter: 20px;
  /* A button's corners, and the notice box's, softer than the brand pack's 2 (D60). */
  --corner: 12px;
  /* The struck crest's on the home page, as the app's launch has them (app/src/theme.ts): the brass of its coin, rule
     and marram, the same in light and dark, the app icon's green it starts from, and the ₿ on the coin. */
  --crest-brass: #C9A55C;
  --green: #2E6B4A;
  --mark: #0E1F3D;
  /* Bitcoin's orange, for four of the starlings round it (D80). */
  --bitcoin: #F7931A;
  /* The linocut's cuts in its sky, for the hero's clouds (D88): slate by day, ivory at night. */
  --cloud: #5C6D77;
}
@media (prefers-color-scheme: dark) {
  :root {
    --ground: #0B1628;
    --surface: #13223A;
    --ink: #EAE4D6;
    --on-ink: #0E1F3D;
    --muted: #A7AFBD;
    --brass: #C9A55C;
    --hairline: #22324D;
    --cloud: #EDECDC;
  }
}

html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font: 16px/24px "Alegreya Sans", sans-serif;
  /* Every figure as tall as a capital and as wide as the rest (D34). */
  font-variant-numeric: lining-nums tabular-nums;
}
header, main, footer { box-sizing: border-box; margin: 0 auto; padding: 0 var(--gutter); }
/* The join page is a narrow column under the crest; a document is a line long enough to read; the home page and the
   page for developers are broad enough for three phones, or a phone and a ledger, side by side. */
.narrow header, .narrow main, .narrow footer { max-width: 26rem; }
.wide header, .wide main, .wide footer { max-width: 38rem; }
.broad header, .broad main, .broad footer { max-width: 60rem; }
main { padding-top: 40px; }
header + main { padding-top: 0; }

a { color: inherit; text-decoration-line: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
@media (hover: hover) {
  a:hover { text-decoration-thickness: 2px; }
}

/* The crest heads the home page and the join page, and a smaller one, which goes home, heads the rest. */
h1 { margin: 0; }
.crest { display: block; width: 200px; height: 200px; margin: 0 auto; }
header { padding-top: 24px; }
.home { display: block; width: 88px; margin: 0 auto; }
.home img { display: block; width: 88px; height: 88px; }

/* The home page's hero (D80): the crest the width of the window, over a linocut of a links whose sky is the page
   itself, which site/hero.js strikes as the app's launch does, at half its speed, in a murmuration of starlings. */
header.hero {
  position: relative;
  max-width: none;
  height: clamp(540px, 86vh, 900px);
  padding: 0;
  overflow: hidden;
  container-type: size;
  --crest: clamp(190px, min(24vw, 36vh), 330px);
}
@media (max-width: 40rem) {
  header.hero { height: 580px; --crest: 200px; }
}
/* The linocut along the foot, the whole width, with its horizon, the top of the sea, no higher than just under the
   crest, nor than seven tenths of the way down, so that on a large screen its foot runs off the hero instead. The
   page gives each file's height for its width and how far down it the horizon is, as --art-height and --art-horizon,
   from site/art/manifest.json. Where the hero can't be measured, it sits at the foot. */
.art img {
  position: absolute;
  left: 0;
  bottom: 0;
  display: block;
  width: 100%;
  height: auto;
  height: calc(100cqw * var(--art-height));
  top: max(
    calc(100cqh - 100cqw * var(--art-height)),
    calc(max(42cqh + var(--crest) / 2 + 24px, 70cqh) - 100cqw * var(--art-height) * var(--art-horizon))
  );
  transition: opacity 1.2s;
}
/* It fades in as it loads, once the hero's script is there to see it. */
.art img.waiting { opacity: 0; transition: none; }
/* The crest, its middle 42% of the way down. The crest as it stands has a margin round it of six hundredths of the
   crest's width. */
.hero h1, .strike {
  position: absolute;
  top: calc(42% - var(--crest) / 2);
  left: calc(50% - var(--crest) / 2);
  width: var(--crest);
  height: var(--crest);
}
.hero .crest { position: absolute; inset: -6%; width: 112%; height: 112%; margin: 0; }
/* While the page can run a script, the crest as it stands waits out of sight for site/hero.js to strike it in its
   place, though for 2.5 s at most, in case it never runs. Once struck, it stays under the struck crest, for those
   who can't see either. */
@media (scripting: enabled) {
  .hero .crest { opacity: 0; animation: unveil 0s 2.5s forwards; }
}
.hero.live .crest { opacity: 0; animation: none; }
@keyframes unveil { to { opacity: 1; } }
/* The clouds, which site/hero.js drifts across the sky, each sliding as it was drawn (D88). */
.clouds { position: absolute; inset: 0; pointer-events: none; }
.clouds svg { position: absolute; top: 0; left: 0; display: block; fill: var(--cloud); will-change: transform; }
/* The flock, over the clouds and under the crest. A finger on it still scrolls the page. */
.flock { position: absolute; inset: 0; display: block; width: 100%; height: 100%; touch-action: pan-y; }
/* The struck crest, which a tap strikes again, and scatters the flock. */
.strike {
  display: block;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: inherit;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
div.strike { cursor: default; }
.strike:focus-visible { outline: 2px solid var(--ink); outline-offset: 8px; }
.strike svg { display: block; width: 100%; height: 100%; }
@media (prefers-reduced-motion: reduce) {
  .art img { transition: none; }
}

/* The double brass rule, as under the app's header: two lines, 2 px apart. */
.rule { height: 2px; margin: 24px 0; border-top: 1px solid var(--brass); border-bottom: 1px solid var(--brass); }

p { margin: 0 0 16px; }
strong { font-weight: 500; }

/* A sentence at a title's size, in Alegreya Sans, as the app sets one (D31), such as the missing page's heading. */
.line { margin: 0 0 16px; font-weight: 500; font-size: 22px; line-height: 28px; }

/* A document's title, which isn't a sentence: the design language's section title. */
.title { margin: 8px 0 8px; font: 600 22px/28px "Cinzel", serif; letter-spacing: 0.06em; text-transform: uppercase; }
/* The line that sets a document in context, in italic. */
.context { font-style: italic; font-size: 17px; line-height: 24px; color: var(--muted); }
.fine { font-size: 15px; line-height: 20px; color: var(--muted); }
/* Words a line doesn't break at their hyphens, such as a library's name and version in the open source licences. */
.whole { white-space: nowrap; }

/* A section's label, in brass capitals, as the app's are. */
h2 {
  margin: 40px 0 12px;
  font: 600 11px/16px "Cinzel", serif;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--brass);
}
ul, ol { margin: 0 0 16px; padding-left: 20px; }
li { margin: 0 0 8px; padding-left: 4px; }

/* A table is a ledger: ruled in ink above and below, with hairlines between its rows, its labels in brass, and each
   row led by its first cell. */
table { width: 100%; margin: 0 0 16px; border-collapse: collapse; border-top: 1px solid var(--ink); border-bottom: 1px solid var(--ink); font-size: 15px; line-height: 20px; }
th, td { padding: 8px 12px 8px 0; text-align: left; vertical-align: top; }
thead th {
  padding-top: 12px;
  vertical-align: bottom;
  font: 600 11px/16px "Cinzel", serif;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--brass);
}
tbody th { font-weight: 500; }
tbody th, td { border-top: 1px solid var(--hairline); }
th:last-child, td:last-child { padding-right: 0; }
/* A table of more than two columns is too wide for a phone, so there each row stands as a block: its first cell, then
   each other cell under its label. */
@media (max-width: 30rem) {
  .stacked thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .stacked, .stacked tbody, .stacked tr, .stacked th, .stacked td { display: block; }
  .stacked tr { padding: 8px 0; }
  .stacked tr + tr { border-top: 1px solid var(--hairline); }
  .stacked tbody th, .stacked td { padding: 0 0 8px; border-top: 0; }
  .stacked td::before {
    content: attr(data-label);
    display: block;
    font: 600 11px/16px "Cinzel", serif;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--brass);
  }
}

/* The notice box: For your guidance stacked on the left, in brass, and one plain sentence on the right. */
.notice { display: flex; align-items: center; gap: 16px; margin: 24px 0; padding: 16px; border: 1px solid var(--brass); border-radius: var(--corner); }
.notice-label { flex: none; font: 600 11px/16px "Cinzel", serif; letter-spacing: 0.2em; text-transform: uppercase; color: var(--brass); }
.notice-label span { display: block; }
.notice p { margin: 0; }

.button {
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  min-height: 52px;
  padding: 0 16px;
  border: 1px solid var(--ink);
  border-radius: var(--corner);
  background: var(--ink);
  color: var(--on-ink);
  font: 600 14px/1 "Cinzel", serif;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  text-decoration: none;
}
.button.plain { border-color: var(--surface); background: var(--surface); color: var(--ink); }
/* As in the app, it fades while pressed. A keyboard's focus is drawn round it in ink. */
.button:active { opacity: 0.55; }
@media (hover: hover) {
  .button:hover { opacity: 0.8; }
}

/* The home page under its hero (D85): what fore:bitcoin is, and beside it on a computer how to join; the store
   listing's six screens, each in a phone's outline over its label and words, three to a row on a computer and in a row
   that scrolls across on a phone, a little of the next one showing; and privacy and safety, its three sentences ruled
   as a ledger is, side by side on a computer. */
.intro { display: grid; gap: 0 64px; }
@media (min-width: 48rem) {
  .intro { grid-template-columns: minmax(0, 1fr) minmax(0, 22rem); align-items: center; }
  .intro .line { font-size: 34px; line-height: 40px; }
  .intro p:last-child { margin-bottom: 0; }
  .intro .notice { margin-top: 0; }
}
.shots { display: flex; gap: 24px; margin: 40px calc(-1 * var(--gutter)) 0; padding: 0 var(--gutter) 8px; overflow-x: auto; list-style: none; scroll-snap-type: x mandatory; scroll-padding: 0 var(--gutter); }
.shots li { flex: none; width: 15rem; margin: 0; padding: 0; text-align: center; scroll-snap-align: start; }
.shots h2 { margin: 20px 0 8px; }
/* Its words in lines of a length, where the browser can, with no word left on a line of its own. */
.shots p { margin: 0; text-wrap: balance; }
.intro p { text-wrap: pretty; }
@media (min-width: 48rem) {
  .shots { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 56px 40px; margin: 56px 0 16px; padding: 0; overflow: visible; }
  .shots li { width: auto; }
}
/* A screen of the app in a phone's outline in ink, as on the page for developers. */
.handset { box-sizing: border-box; width: 100%; max-width: 15rem; margin: 0 auto; padding: 8px; border: 1.5px solid var(--ink); border-radius: 40px; }
.handset img { display: block; width: 100%; height: auto; border-radius: 32px; }
.kept h2 { margin-top: 32px; }
/* A section's sentence at a title's size, as the app sets one (D31). */
.statement { margin: 0 0 24px; font-weight: 500; font-size: 22px; line-height: 28px; }
.facts { margin: 0 0 40px; padding: 0; border-top: 1px solid var(--ink); border-bottom: 1px solid var(--ink); list-style: none; }
.facts li { margin: 0; padding: 16px 0; }
.facts li + li { border-top: 1px solid var(--hairline); }
@media (min-width: 48rem) {
  .facts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .facts li { padding: 20px 24px 24px; }
  .facts li:first-child { padding-left: 0; }
  .facts li:last-child { padding-right: 0; }
  .facts li + li { border-top: 0; border-left: 1px solid var(--hairline); }
}

footer { margin-top: 40px; padding-bottom: 40px; font-size: 15px; line-height: 20px; color: var(--muted); }
footer .rule { margin-top: 0; }
.links { display: flex; flex-wrap: wrap; gap: 8px 24px; margin: 0 0 16px; padding: 0; list-style: none; }
.links li { margin: 0; padding: 0; }
.links a { display: inline-block; padding: 12px 0; color: var(--ink); }

/* The page for developers (D81): the app's journeys to tap through, in a phone's outline, and beside them, or under
   them on a phone, the ledger of how it's made. site/inside.js makes the phone from the journeys' screens, which stand
   in rows without it. The phone is as tall as the window allows, with the journeys above it and its buttons below. */
.inside {
  display: grid;
  gap: 24px 64px;
  margin-top: 32px;
  --phone: clamp(250px, calc(45vh - 97px), 340px);
  --phone: clamp(250px, calc(45svh - 97px), 340px);
}
/* With the script, the phone comes first, then the ledger, and the rows of screens last, out of sight. */
.player { order: 1; }
.recorded { order: 2; }
.made { order: 3; }
.journeys { order: 4; }
@media (min-width: 58rem) {
  .inside { grid-template-columns: minmax(0, 30rem) minmax(0, 1fr); align-items: start; }
  .player, .recorded { grid-column: 1; }
  .made { grid-column: 2; grid-row: 1 / span 2; }
  .journeys { grid-column: 1 / -1; }
}
.recorded { margin: 0; text-align: center; }
.made h2 { margin-top: 14px; }
.made table { margin: 0; }
.made th { width: 30%; }
/* The ledger has no labels above it, so its first row has the ink rule over it. */
.made tbody tr:first-child > * { border-top: 0; }

.player { display: flex; flex-direction: column; align-items: center; gap: 16px; justify-self: center; width: 100%; max-width: 30rem; }
/* The journeys, each over a hairline, and the one on the phone in ink, its hairline inked as far as it has gone. */
.tabs { display: flex; flex-wrap: wrap; gap: 4px 16px; align-self: stretch; }
.tabs button, .controls button {
  min-height: 44px;
  border: 0;
  background: none;
  font: 600 11px/16px "Cinzel", serif;
  text-transform: uppercase;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.tabs button { position: relative; flex: 1 1 auto; padding: 0; border-bottom: 1px solid var(--hairline); color: var(--muted); letter-spacing: 0.12em; }
.tabs button[aria-pressed="true"] { color: var(--ink); }
.progress { position: absolute; left: 0; right: 0; bottom: -1px; height: 2px; background: var(--ink); transform: scaleX(0); transform-origin: left; transition: transform 0.3s; }
.tabs button:focus-visible, .controls button:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
/* The phone: an outline in ink round the screen. */
.phone { box-sizing: border-box; width: min(var(--phone), 100%); padding: 8px; border: 1.5px solid var(--ink); border-radius: 40px; }
.glass { position: relative; overflow: hidden; aspect-ratio: 720 / 1600; border-radius: 32px; background: var(--surface); }
/* A screen fades in over the one before, which goes once it has. */
.glass img { position: absolute; inset: 0; display: block; width: 100%; height: 100%; opacity: 0; transition: opacity 0s 0.22s; }
.glass img.front { z-index: 1; opacity: 1; transition: opacity 0.22s; }
.glass img.instant { transition: none; }
/* The screens' look, light or dark, as the visitor's phone or computer is until they pick, sets the tap's brass: the
   darker brass of the labels on light, which the screens' white and their buttons' ink both show, and the brighter on
   dark. */
.glass.light { --brass: #8A6A2B; }
.glass.dark { --brass: #C9A55C; }
/* A screen that won't load, in words. */
.lost { position: absolute; inset: 0; z-index: 2; display: none; place-items: center; margin: 0; padding: 24px; text-align: center; font-size: 15px; line-height: 20px; color: var(--muted); }
.glass.missing .lost { display: grid; }
.glass.missing img { visibility: hidden; }
/* The launch, as the app opens (app/src/splash/CrestSplash.tsx), over the screen it fades to: on its ground, white or
   navy, in its colours, and in dark with the tool's seat round the coin letting the green show through
   (app/src/theme.ts, launch). It comes at once, as the app does, and hands over as the app does (D87,
   app/src/splash/timeline.ts): the crest fades from its ground, then the ground lifts off the screen. */
.launch { position: absolute; inset: 0; z-index: 2; display: grid; place-items: center; background: var(--ground); }
.launch svg { display: block; aspect-ratio: 1; height: auto; }
.launch.gone { opacity: 0; visibility: hidden; transition: opacity 0.35s cubic-bezier(0.65, 0, 0.35, 1) 0.15s, visibility 0s 0.5s; }
.launch.gone svg { opacity: 0; transition: opacity 0.25s cubic-bezier(0.65, 0, 0.35, 1); }
.glass.light .launch { --ground: #FFFFFF; --ink: #0E1F3D; --green: #2E6B4A; --crest-brass: #C9A55C; --mark: #0E1F3D; --seat: #FFFFFF; }
.glass.dark .launch { --ground: #0E1F3D; --ink: #EAE4D6; --green: #2E6B4A; --crest-brass: #C9A55C; --mark: #0E1F3D; --seat: transparent; }
/* The tap, in brass, as a fingertip: it shows, presses, calls while the visitor leads, and jumps when a tap misses. */
.ring {
  position: absolute;
  z-index: 3;
  width: 13%;
  aspect-ratio: 1;
  border: 2px solid var(--brass);
  border-radius: 50%;
  background: color-mix(in srgb, var(--brass) 28%, transparent);
  opacity: 0;
  transform: translate(-50%, -50%) scale(0.6);
  transition: opacity 0.25s, transform 0.25s;
  pointer-events: none;
}
.ring.on { opacity: 1; transform: translate(-50%, -50%) scale(1); }
.ring.press { background: color-mix(in srgb, var(--brass) 55%, transparent); transform: translate(-50%, -50%) scale(0.82); transition-duration: 0.12s; }
.ring.call::after { content: ""; position: absolute; inset: -2px; border: 2px solid var(--brass); border-radius: 50%; animation: call 1.6s ease-out infinite; }
.ring.nudge { animation: nudge 0.4s; }
@keyframes call { from { opacity: 0.9; transform: scale(1); } to { opacity: 0; transform: scale(1.9); } }
@keyframes nudge { 35% { transform: translate(-50%, -50%) scale(1.3); } }
/* What the tap lands on, which a keyboard reaches too. */
.hit { position: absolute; z-index: 4; padding: 0; border: 0; border-radius: 12px; background: none; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.hit:focus-visible { outline: 2px solid var(--brass); outline-offset: -2px; }
.controls { display: flex; justify-content: center; gap: 4px; }
.controls button { min-width: 88px; padding: 0 12px; border-radius: var(--corner); color: var(--ink); letter-spacing: 0.2em; }
.controls button:disabled { color: var(--muted); cursor: default; }
.tabs button:active, .controls button:active:not(:disabled) { opacity: 0.55; }
@media (hover: hover) {
  .tabs button:hover { color: var(--ink); }
  .controls button:hover:not(:disabled) { background: var(--surface); }
}
/* Light or dark, as the app's chips are: soft, and the one picked in ink. */
.looks { display: flex; justify-content: center; gap: 8px; }
.looks button {
  min-height: 40px;
  padding: 0 16px;
  border: 0;
  border-radius: var(--corner);
  background: var(--surface);
  color: var(--ink);
  font: 17px/22px "Alegreya Sans", sans-serif;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.looks button[aria-pressed="true"] { background: var(--ink); color: var(--on-ink); }
.looks button:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.looks button:active { opacity: 0.55; }
/* What's said aloud as the visitor leads, for those who can't see the screen. */
.heard { position: absolute; width: 1px; height: 1px; margin: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
@media (prefers-reduced-motion: reduce) {
  .glass img, .glass img.front, .launch.gone, .launch.gone svg, .ring, .progress { transition: none; }
  .ring.call::after { animation: none; }
}

/* Without the script, each journey is a row of its screens. */
.journey h2 { margin-top: 24px; }
.screens { display: flex; gap: 12px; margin: 0; padding: 0 0 12px; overflow-x: auto; list-style: none; scroll-snap-type: x mandatory; }
.screens li { flex: none; width: 160px; margin: 0; padding: 0; scroll-snap-align: start; }
.screens img { display: block; width: 100%; height: auto; border: 1px solid var(--hairline); border-radius: 16px; }
@media (scripting: none) {
  .inside { display: block; }
  .player { display: none; }
}
/* While the page can run a script, the rows wait out of sight for site/inside.js to make the phone, in the room the
   phone will take, though for 3 s at most, in case it never runs. */
@media (scripting: enabled) {
  .inside:not(.live) .player { min-height: calc((var(--phone) - 19px) * 2.2222 + 196px); animation: unwait 0s 3s forwards; }
  .inside:not(.live) .journeys { height: 0; margin-top: -24px; overflow: hidden; visibility: hidden; animation: unwait 0s 3s forwards; }
}
/* On a phone, the journeys take two rows. */
@media (scripting: enabled) and (max-width: 33rem) {
  .inside:not(.live) .player { min-height: calc((var(--phone) - 19px) * 2.2222 + 244px); }
}
.inside.live .journeys { display: none; }
@keyframes unwait { to { min-height: 0; height: auto; margin-top: 0; overflow: visible; visibility: visible; } }

[hidden] { display: none; }
