/*
 * The house style, shared by every page on corefolios.com.
 *
 * Lifted from the apps themselves rather than invented here: the same ivory
 * ground, the same faint vertical rules, the same Baskerville display face,
 * the same clay for anything you press — and, on the encore page, the same
 * eight shelf colours the app's own category strip wears. A website that looks
 * like the product is worth more than a website that looks like a website.
 *
 * Prose sits in a 680px column, the family's written standard. Anything that
 * is a picture rather than a sentence is allowed to go wider, because a
 * screenshot squeezed into a reading measure looks like an apology.
 */

:root {
  --ivory: #e6dbd2;
  --paper: #f7f2ec;
  --surface: #fbf8f3;
  --espresso: #2e2723;
  --muted: #6b5f56;
  --line: rgba(100, 75, 55, .2);
  --hair: rgba(100, 75, 55, .1);
  --shadow: rgba(70, 52, 38, .16);
  --deep: rgba(70, 52, 38, .26);
  --clay: #aa8c72;
  --clay-soft: #c2b2a6;

  /*
   * encore's eight shelves — sampled from the running app, not re-derived.
   *
   * These were first worked out from CATEGORY_COLOUR's oklch expressions mixed
   * 62% into paper, which is one of several mixes the app uses and not the one
   * the category strip actually wears. The result was right in hue and too
   * saturated in every case. Jess: "the shelve colours should be the same as
   * the app". So they are now read straight off a v1.2 screenshot — the thing
   * she is comparing against — rather than computed a second way and hoped.
   */
  --film: #e2d6cd;
  --tv: #cec2b3;
  --theatre: #e4d3cc;
  --music: #c0b7a7;
  --podcast: #e8dad6;
  --book: #d0ccbd;
  --game: #cbb9b7;
  --event: #e4deda;

  --display: Baskerville, "Baskerville Old Face", Georgia, serif;
  --utility: Optima, Candara, "Gill Sans", "Avenir Next", sans-serif;

  --measure: 680px;
  --wide: 1040px;
}

/* Dark is defined once and applied twice — by the system preference and by an
   explicit choice — so neither can leave a colour undefined. The shelf tints
   are darkened rather than dropped: the strip is the app's signature, and a
   row of grey boxes at night is not it. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ivory: #1c1815;
    --paper: #262019;
    --surface: #2b241e;
    --espresso: #f2e9df;
    --muted: #b6a99b;
    --line: rgba(255, 250, 242, .18);
    --hair: rgba(255, 250, 242, .08);
    --shadow: rgba(0, 0, 0, .5);
    --deep: rgba(0, 0, 0, .68);
    --film: #6b573f;
    --tv: #5f4f36;
    --theatre: #7a5344;
    --music: #55502f;
    --podcast: #7c5750;
    --book: #545138;
    --game: #6b4744;
    --event: #453f3a;
  }
}
:root[data-theme="dark"] {
  --ivory: #1c1815;
  --paper: #262019;
  --surface: #2b241e;
  --espresso: #f2e9df;
  --muted: #b6a99b;
  --line: rgba(255, 250, 242, .18);
  --hair: rgba(255, 250, 242, .08);
  --shadow: rgba(0, 0, 0, .5);
  --deep: rgba(0, 0, 0, .68);
  --film: #6b573f;
  --tv: #5f4f36;
  --theatre: #7a5344;
  --music: #55502f;
  --podcast: #7c5750;
  --book: #545138;
  --game: #6b4744;
  --event: #453f3a;
}

* { box-sizing: border-box; }

html {
  background: var(--ivory);
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

/*
 * The ground.
 *
 * A warm wash and a pool of light at the top. Nothing else.
 *
 * There were vertical rules here, borrowed from the app's own paper. They were
 * softened once and Jess still saw them — "the background lines are still a bit
 * intense" — which is the answer: a texture you keep noticing is not a texture,
 * it is a pattern. Something meant to be felt rather than read has failed the
 * moment somebody mentions it twice, and the honest fix is to take it out
 * rather than keep halving it.
 */
body {
  margin: 0;
  color: var(--espresso);
  font-family: var(--display);
  font-size: 17.5px;
  line-height: 1.65;
  /* All three layers scroll with the page. A fixed one drew a visible seam
     where the viewport ended on a long page, and iOS Safari repaints fixed
     backgrounds badly on every scroll — neither is worth the parallax. */
  background:
    radial-gradient(120% 40% at 50% 0%, var(--surface), transparent 62%),
    linear-gradient(168deg, var(--ivory), var(--paper) 46%, var(--ivory));
}

main {
  max-width: var(--measure);
  margin: 0 auto;
  /*
   * The notch and the home indicator, guarded against rather than fixed.
   *
   * Honest about what this does today: **nothing**. `env(safe-area-inset-*)`
   * resolves to zero unless the viewport tag carries `viewport-fit=cover`, and
   * this site's does not — which is why Safari already keeps the page clear of
   * the notch, and why the site is not in fact cut off by it.
   *
   * It stays because the day somebody adds `viewport-fit=cover` for a
   * full-bleed hero, this is the line that stops the first letter of every
   * paragraph disappearing under a rounded corner, and that day nobody will
   * remember to add it. max() keeps 26px as the floor, so the inset can only
   * ever widen the gutter.
   */
  padding: 0 max(26px, env(safe-area-inset-right)) 0 max(26px, env(safe-area-inset-left));
}

/* The foot of the page clears the home indicator. */
body { padding-bottom: env(safe-area-inset-bottom); }

/* Anything allowed out of the reading column. */
.wide {
  max-width: var(--wide);
  margin-left: auto;
  margin-right: auto;
  /*
   * The same gutter `main` has, because this sits *outside* it.
   *
   * Jess: "the page which doesn't look good on phone is when you click on
   * encore." Every feature block on that page lives in a `.wide` container that
   * closes after `</main>`, so it never inherited main's 26px — and `.wide` set
   * only a max-width. On a desktop the 1040px cap leaves space either side and
   * it looks deliberate; on a 393px phone the block is the full width with
   * nothing at the edges, so "Where you start" began at pixel zero and the line
   * under it ran off the right.
   *
   * Nothing overflowed, which is why a scrollWidth check found nothing wrong
   * three times. The text was inside the viewport and hard against both sides
   * of it.
   */
  padding-left: max(26px, env(safe-area-inset-left));
  padding-right: max(26px, env(safe-area-inset-right));
}

/* ── Type ─────────────────────────────────────────────────────────────────── */

h1 {
  margin: 0;
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(32px, 7vw, 58px);
  letter-spacing: .22em;
  text-transform: uppercase;
  /* Uppercase letter-spacing pads the right edge; pull it back to centre. */
  text-indent: .22em;
  line-height: 1.12;
}

h2 {
  margin: 0;
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(26px, 5vw, 38px);
  line-height: 1.18;
}

h3 {
  margin: 0;
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(21px, 3.4vw, 27px);
  line-height: 1.25;
}

.eyebrow {
  display: block;
  font-family: var(--utility);
  font-size: 10px;
  letter-spacing: .28em;
  text-transform: uppercase;
  color: var(--muted);
}

.lede {
  font-family: var(--display);
  font-size: clamp(19px, 3.3vw, 25px);
  font-style: italic;
  line-height: 1.5;
  color: var(--muted);
  text-wrap: balance;
}

/* A hairline that is a piece of punctuation rather than a border. */
.rule {
  width: 58px;
  height: 1px;
  margin: 0 auto;
  background: var(--line);
  border: 0;
}

/* ── Anything you press ───────────────────────────────────────────────────── */

.button {
  display: inline-block;
  padding: 17px 34px;
  min-height: 44px;
  border: 1px solid transparent;
  /*
   * Espresso, with the paper as its ink.
   *
   * This is the one hard call to action on the site, and it had been two
   * shades of clay in a row — the brown under near-white read muddy at 3.0:1,
   * and the soft clay that replaced it was too pale to lead a page. The
   * house's own dark does the job, sits beside Apple's black badge without
   * arguing, and clears AA comfortably.
   */
  background: var(--espresso);
  color: var(--paper);
  font-family: var(--utility);
  font-size: 10.5px;
  letter-spacing: .22em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  box-shadow: 0 6px 18px var(--shadow);
  transition: transform .22s ease, box-shadow .22s ease;
}

.button:hover {
  transform: translateY(-2px);
  box-shadow: 0 10px 26px var(--deep);
}

.button.quiet {
  background: transparent;
  border-color: var(--line);
  color: var(--espresso);
  box-shadow: none;
}

.button.quiet:hover { border-color: var(--clay); box-shadow: none; }

a:focus-visible,
button:focus-visible,
input:focus-visible,
summary:focus-visible {
  outline: 2px solid var(--espresso);
  outline-offset: 3px;
}

/* ── A phone ──────────────────────────────────────────────────────────────── */

/*
 * Screenshots are given a bezel.
 *
 * Without one they read as a picture of a screen; with one they read as a
 * thing you could hold, which is the whole difference between a product page
 * and a bug report. The frame is a thin dark rim and a bright inner hairline —
 * the way light actually catches a phone edge — not a photographed device,
 * which would date the page the moment the hardware changes.
 */
.phone {
  position: relative;
  padding: 7px;
  border-radius: 30px;
  background: linear-gradient(160deg, #4a4038, #2b2521 40%, #4a4038);
  box-shadow: 0 24px 54px var(--deep), 0 2px 5px var(--shadow);
}

.phone::after {
  content: "";
  position: absolute;
  inset: 6px;
  border-radius: 25px;
  border: 1px solid rgba(255, 246, 234, .18);
  pointer-events: none;
}

.phone img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 24px;
}

/* ── Arriving ─────────────────────────────────────────────────────────────── */

.rise {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity .7s ease, transform .7s ease;
}
.rise.here { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .rise { opacity: 1; transform: none; transition: none; }
  .button:hover { transform: none; }
}

/* ── Footer ───────────────────────────────────────────────────────────────── */

footer {
  margin: clamp(88px, 15vh, 150px) 0 0;
  padding: clamp(40px, 6vh, 60px) 0 clamp(56px, 10vh, 104px);
  border-top: 1px solid var(--hair);
  text-align: center;
}

/*
 * 44px tall, like every other target.
 *
 * These were 26px — 10px type on a 2.6 line-height — which is fine to look at
 * and too small to hit on a phone. The padding replaces the margin rather than
 * adding to it, so the row looks exactly as it did and is simply easier to
 * press.
 */
footer nav a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  margin: 0;
  padding: 0 12px;
  line-height: 1.4;
  color: var(--muted);
  font-family: var(--utility);
  font-size: 10px;
  letter-spacing: .18em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
}

footer nav a:hover { color: var(--espresso); }

footer .small {
  margin: 18px 0 0;
  font-size: 13.5px;
  font-style: italic;
  color: var(--muted);
}
