/* THE PAGES' CHROME: what About, Terms and Privacy all wear, so the three
   read as one site. The type scale and the grid, the fixed bar with the
   wordmark, the theme toggle and Open Set, prose links, the label and the
   footer. It lives in about/ because that tree ships wherever the About page
   does (both packs and the hosted root), and the legal pages, which are
   hosted only, reach it at the same relative path. Each page's own layout
   stays with the page: About's stage and grid in about.html, the legal
   documents' column in site/site.css. */

html, body { height: auto; overflow: auto; }
/* styles.css was written for a studio that fills the window and never
   scrolls, so it pins html and body to the viewport with overflow hidden.
   These are documents: the rule above gives the scroll back. Everything
   below is on the app's tokens wherever a token names the thing sized. */

/* THE PAGE'S TYPE SCALE, adapted from the reference page for Figtree. Fixed
   pixels and no fluid clamp. The reading never changes size at a breakpoint;
   the one thing set in type that does is the poster, which is not reading
   (on the stage a line is a screen), and its 680 rule says why. The app's
   own --font-h1 is 20px because it heads a sidebar; these are named --fs-*
   so the two scales cannot be mistaken for one another. Figtree is a
   humanist sans and loses apparent weight small, which is why the label is
   500 and not 400. */
:root {
  --fs-label: 12px;  --lh-label: 16px;
  --fs-body: 15px;   --lh-body: 24px;
  --fs-h3: 17px;     --lh-h3: 24px;
  --fs-lead: 20px;   --lh-lead: 28px;
  --fs-h2: 28px;     --lh-h2: 36px;
  --fs-h1: 44px;     --lh-h1: 48px;

  /* The grid is three numbers. The track is the reading width, the gutter
     is both the page inset and the space between columns, and the measure
     is how long a line of prose may run: at 15px a paragraph across the
     whole 1170 track is 150 characters to the line, which nobody reads. */
  --track: 1170px;
  --gutter: 24px;
  --measure: 600px;

  /* THE GUTTER IS A MINIMUM, NOT THE WHOLE INSET. The pages are served
     viewport-fit=cover, so on a phone held sideways the window reaches under
     the notch and the rounded corners, and a bare 24 put the first letter of
     every line beneath them. Every block that sets the page's side inset
     takes these instead: the bar, About's sections, the legal column and the
     footer. --edge-b is the home indicator, which only the footer stands
     over. */
  --edge-l: max(var(--gutter), env(safe-area-inset-left));
  --edge-r: max(var(--gutter), env(safe-area-inset-right));
  --edge-b: env(safe-area-inset-bottom, 0px);

  /* ONE GAP BETWEEN THE PAGE'S BLOCKS: stage to studio, studio to pricing,
     pricing to That's the set., and that to the footer. On the 8px grid, 24
     steps, stepping down with the window (the narrower breakpoints below). A
     fraction of the window's height came first and read too tight, and
     cannot hold a grid step anyway. */
  --section-gap: 192px;
}

body {
  background: var(--ground);
  color: var(--ink);
  font: 400 var(--fs-body) / var(--lh-body) var(--font);
  -webkit-text-size-adjust: 100%;
}

/* An <a> wearing .btn is a button, and a button carries no underline. */
a.btn { text-decoration: none; }

/* ---------- the bar ---------- */

/* Fixed, and transparent where it matters: over the stage. No glass and no
   border. What it does carry is a FIELD of the ground, solid behind its own
   64px and running out over 24px below them, and that is for the reading,
   not the stage. The prose scrolls under a fixed bar: below about 1500px the
   track reaches the toggle and the button, and on a phone it reaches the
   wordmark itself, so a bare bar puts a line of body text through "set".
   Solid for the whole height, because the first build faded from halfway
   down and the lead showed through at half strength behind the wordmark,
   which is worse than either. The run-out is eased, not linear, because the
   eye finds the corner at the end of a straight ramp.
   AND THE FIELD IS OFF OVER A PICTURE (.bare, installBarField in chrome.js).
   This was written believing the field could not be seen over the stage,
   since the canvas is transparent and the ground behind it is the page's;
   the stage is a dark ROOM, and the band read as black ruled across the top
   of the frame with a fade under it, cutting the block and its words. A bar
   over a picture is transparent or it is a lid. The swap itself cannot be
   seen: it happens as the stage leaves the window, where what stands under
   the bar is the section gap, which is the ground the field paints. */
.topbar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 20;
  height: 64px;
  padding-left: var(--edge-l);
  padding-right: var(--edge-r);
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.topbar::before {
  content: '';
  position: absolute;
  inset: 0 0 -24px;
  z-index: -1;
  background: var(--ground);
  pointer-events: none;
  --run-out: linear-gradient(to bottom, #000 0%, rgba(0, 0, 0, 0.92) 17%, rgba(0, 0, 0, 0.74) 33%, rgba(0, 0, 0, 0.5) 50%, rgba(0, 0, 0, 0.26) 67%, rgba(0, 0, 0, 0.08) 83%, transparent 100%);
  -webkit-mask-image: linear-gradient(#000, #000), var(--run-out);
  mask-image: linear-gradient(#000, #000), var(--run-out);
  -webkit-mask-size: 100% calc(100% - 24px), 100% 24px;
  mask-size: 100% calc(100% - 24px), 100% 24px;
  -webkit-mask-position: top left, bottom left;
  mask-position: top left, bottom left;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
}

/* No field at all while the bar stands over a picture. Not a fade: there is
   nothing to ease between, and a fade would paint the band over the stage's
   last pixels for as long as it ran. */
.topbar.bare::before { display: none; }

/* The sidebar's wordmark exactly (#panel-head h1), so the link from the app
   and the page it opens are headed by the same word set the same way. Focus
   shows in the link's own language, its colour, as it does in the app. */
.wordmark {
  font-size: var(--font-h1);
  font-weight: var(--weight-bold);
  letter-spacing: -0.02em;
  line-height: var(--leading-tight);
  color: var(--ink);
  text-decoration: none;
  transition: color 0.2s ease;
}

@media (hover: hover) {
  .wordmark:hover { color: var(--ink-2); }
}

.wordmark:focus-visible { color: var(--ink-2); }

.topnav {
  display: flex;
  align-items: center;
  gap: var(--space-1);
}

/* ---------- prose ---------- */

/* Links in prose are ink on ink-2 text with a hairline under them. The line
   is text-decoration on the word, which the design rule allows because it is
   the link, not a divider; focus shows as the hover does, in colour. */
main a:not(.btn) {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-decoration-color: var(--border-strong);
  text-underline-offset: 3px;
  transition: color 0.2s ease;
}

/* HOVER IS A POINTER'S ANSWER AND A PHONE HAS NONE: a tap leaves :hover
   standing on whatever was last touched, so every rule that paints one is
   asked for a hover-capable pointer first. Focus keeps its own line outside
   the query, because a keyboard reaches every page.
   This rule had lost its second half: it read `main a:not(.btn):hover,` with
   the next COMMENT between it and `.label`, so the two were one selector list
   and a hovered link took the label's declarations. Measured on Privacy: a
   link at rest is 15px ink, and under the pointer it became 12px uppercase
   grey with letterspacing. On a phone that is worse than on a desktop, since
   a tapped link keeps :hover and stays a label. */
@media (hover: hover) {
  main a:not(.btn):hover { color: var(--ink-2); }
}

main a:not(.btn):focus-visible { color: var(--ink-2); }

/* The label, the heading and the body each add something. The label may
   share a word with the heading; the body never says it a third time. */
.label {
  margin-bottom: var(--space-1);
  font-size: var(--fs-label);
  line-height: var(--lh-label);
  font-weight: var(--weight-medium);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-3);
}

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

.footer {
  max-width: calc(var(--track) + 2 * var(--gutter));
  margin: 0 auto;
  /* 64 under the last line, half that on a phone, where 64 read as the page
     stopping a thumb early: the It's Time page's footer, on the grid. */
  padding: var(--section-gap) var(--edge-r) calc(64px + var(--edge-b)) var(--edge-l);
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-2) var(--space-3);
  font-size: var(--fs-label);
  line-height: var(--lh-label);
  color: var(--ink-3);
}

.footer nav { display: flex; gap: var(--space-3); }

.footer a {
  color: inherit;
  text-decoration: none;
  transition: color 0.2s ease;
}

@media (hover: hover) {
  .footer a:hover { color: var(--ink); }
}

.footer a:focus-visible { color: var(--ink); }

/* ---------- a finger ---------- */

/* THE CHROME IS DRAWN FOR A POINTER AND TAPPED BY A THUMB. The controls are
   the app's own sizes, which is the point of sharing its tokens: the toggle
   is 32 square, Open Set 85 by 32, the wordmark is 27 by 24 of set type and
   a footer link is 39 by 16. Every one of those is under the 44px a finger
   asks for, measured at every width this site is read at. What is WRONG with
   them is the target, not the size: a bar of 44px controls on a phone is a
   toolbar, and the page would stop looking like the studio it heads.
   So the target grows and the control does not. A centred box of at least
   44px, painted with nothing, is laid over each control; it is the control's
   own pseudo-element, so a press on it presses the control, and it is
   absolute, so nothing moves. Under a coarse pointer only: on a desktop
   there is nothing to fix and a 44px box around a 24px wordmark would take
   presses meant for the page.
   Gaps were checked against it: the footer's pair stand --space-3 apart and
   grow 6px a side, the bar's three stand --space-1 apart and grow 6, so no
   two boxes meet. */
@media (pointer: coarse) {
  .wordmark,
  .icon-btn,
  .btn,
  .footer a { position: relative; }

  .wordmark::after,
  .icon-btn::after,
  .btn::after,
  .footer a::after {
    content: '';
    position: absolute;
    left: 50%;
    top: 50%;
    width: max(100%, 44px);
    height: max(100%, 44px);
    transform: translate(-50%, -50%);
  }
}

/* ---------- narrower windows ---------- */

@media (max-width: 900px) {
  :root { --section-gap: 160px; }
}

/* 680 is the one breakpoint that changes more than the grid: the gutter
   comes in to 16 and the gap between blocks to 120. */
@media (max-width: 680px) {
  :root { --gutter: 16px; --section-gap: 120px; }
  .footer { padding-bottom: calc(var(--space-4) + var(--edge-b)); }
}
