/* The link-in-bio page.
 *
 * A SEPARATE FILE RATHER THAN AN INLINE <style>, and that is not a preference.
 * netlify.toml sets `style-src 'self'` with no 'unsafe-inline', so a <style>
 * element in the document is parsed, inserted, and then refused: the element is
 * in the DOM with its text intact and its .sheet is null. The page serves 200,
 * the markup is correct, and every rule silently does nothing.
 *
 * It passed local checks because the Eleventy dev server sends no CSP. The
 * measurements were real; they were taken in the one environment where the bug
 * cannot happen. Anything checked on localhost has to be checked again on the
 * deploy.
 */

/* THE BACKGROUND, which is the thing a link page is judged on before a word of
 * it is read. A flat page reads as a placeholder; Linktree charges for this at
 * the Pro tier and it is one gradient and one photograph here.
 *
 * The photo is the board shot, blurred hard and held at low opacity — it is
 * atmosphere, not an image, and at full strength it would fight every button on
 * top of it. `fixed` so it does not slide under the list while scrolling, which
 * is what makes it read as a backdrop rather than as the first card.
 *
 * -1 z-index on a ::before rather than a background on <body>, so the blur
 * cannot bleed onto the content and no stacking context is created that the
 * buttons then have to fight. */
.bio-page { position: relative; min-height: 100vh; }

.bio-page::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  background:
    radial-gradient(120% 80% at 50% 0%, var(--orange-soft) 0%, transparent 62%),
    url("/assets/photos/board.webp") center 18% / cover no-repeat;
  opacity: 0.16;
  filter: blur(3px) saturate(1.1);
}

.bio { position: relative; max-width: 460px; margin: 0 auto; padding: 32px 20px 56px; }

/* ---------------------------------------------------------------- header */
.bio-head { text-align: center; margin-bottom: 26px; }

.bio-head img {
  display: block;
  width: 96px; height: 96px;
  margin: 0 auto 14px;
  border-radius: 50%;
  object-fit: cover;
  box-shadow: 0 0 0 3px var(--paper), 0 0 0 5px var(--orange);
}

.bio-head h1 {
  font-size: 26px; line-height: 1.15; letter-spacing: -0.025em;
  margin: 0 0 6px;
}

.bio-head .at {
  font-family: var(--mono); font-size: 12px; color: var(--muted);
  letter-spacing: 0.06em; text-transform: uppercase; margin: 0;
}

.bio-head .blurb {
  color: var(--muted); font-size: 15px; line-height: 1.5;
  margin: 12px auto 0; max-width: 30ch;
}

/* ---------------------------------------------------------------- buttons */
.bio-links { display: grid; gap: 12px; }

/* One rule for every button so they read as one control repeated, which is what
   makes a page like this scannable in a second. 60px clears the 44px touch
   minimum with room for a thumb that is not being careful. */
/* Three columns where there is a platform mark, two where there is not — the
 * mark column collapses to nothing rather than leaving a gap, so the site links
 * and the channel links still line up as one list. */
.bio-links a {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 6px 14px;
  min-height: 60px;
  padding: 13px 20px;
  background: var(--paper);
  color: var(--ink);
  text-decoration: none;
  border: 1.5px solid var(--ink);
  border-radius: 999px;
  box-shadow: 0 2px 0 var(--ink);
  transition: transform 0.12s ease, box-shadow 0.12s ease, background 0.12s ease;
}

.bio-links a:hover,
.bio-links a:focus-visible {
  background: var(--orange-soft);
  transform: translateY(2px);
  box-shadow: 0 0 0 var(--ink);
}

.bio-links a .n { font-weight: 700; font-size: 16.5px; letter-spacing: -0.01em; }

.bio-links a .meta {
  font-family: var(--mono); font-size: 11px; font-weight: 500;
  color: var(--muted); letter-spacing: 0.05em; text-align: right;
  line-height: 1.35;
}

/* The one commercial destination, so it is the one that looks different.
 *
 * --orange-on, NOT #fff, and this file had the same bug the inline version did
 * before it was caught in review. The orange inverts between themes: the light
 * fill is dark (#b85206, white reads 4.94:1) and the dark-mode fill is light
 * (#f5892c, where white is 2.47:1). --orange-on exists to hold exactly that
 * difference and resolves to ink on dark, which reads 7.21:1.
 *
 * The meta line is at full strength rather than dimmed to rgba(255,255,255,.82),
 * which blended to 3.85:1 in light and 2.11:1 in dark. 11px mono at weight 500
 * against 16.5px sans at 700 is already a clear second rank without spending
 * contrast on it.
 *
 * Hover inverts to ink instead of brightening the fill. Brightening lightens the
 * background underneath text that cannot get any lighter — 4.94 to 4.48, under
 * the line — and axe does not evaluate hover states, so nothing would report it.
 * Inverting is what .btn-orange already does everywhere else on the site. */
.bio-links a.primary {
  background: var(--orange); border-color: var(--ink); color: var(--orange-on);
}
.bio-links a.primary .meta { color: var(--orange-on); }
.bio-links a.primary:hover,
.bio-links a.primary:focus-visible {
  background: var(--ink); border-color: var(--ink); color: var(--paper);
}
.bio-links a.primary:hover .meta,
.bio-links a.primary:focus-visible .meta { color: var(--paper); }

/* ---------------------------------------------------------------- dividers */
.bio-rule {
  margin: 26px 0 13px;
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--muted); text-align: center;
}

.bio-foot {
  margin-top: 32px; text-align: center;
  font-family: var(--mono); font-size: 11px; letter-spacing: 0.04em;
  color: var(--muted);
}
.bio-foot a { color: var(--muted); }

@media (prefers-reduced-motion: reduce) {
  .bio-links a { transition: none; }
  .bio-links a:hover, .bio-links a:focus-visible { transform: none; }
}

/* ---------------------------------------------------------------- marks */
/* Brand colour on the glyph, ink on the label. The mark is the fastest thing to
   recognise in a list of six — colour is what makes it faster than the word next
   to it — but a row of six saturated logos would out-shout the one orange button
   that matters, so they sit at the size of the text rather than above it. */
.bio-links a .mark { display: block; }
.mark-facebook  { color: #0866ff; }
.mark-instagram { color: #e1306c; }
.mark-tiktok    { color: var(--ink); }
.mark-youtube   { color: #ff0033; }
.mark-threads   { color: var(--ink); }

/* The primary button paints its own text colour, so the mark follows it rather
   than staying brand-coloured on an orange fill. */
.bio-links a.primary .mark { color: inherit; }

/* "New" on a young channel. It sits in the META column, standing in for the
   follower count rather than beside the name.

   It was in the label, on the reasoning that "YouTube, new" reads as one thing
   and keeps it from competing with the number opposite. That was true in
   isolation and wrong in the row: a channel under 100 hides its count, so the
   right-hand cell rendered EMPTY while every row above it ended in a number,
   and an empty cell in an aligned column reads as broken or still loading. The
   tag is not competing with the count — it is what there is to say instead of
   one, so it belongs where the count would have been.

   No margin-left: it is alone in a right-aligned cell now, and the old 8px was
   spacing it off a label that is no longer beside it. */
.bio-links a .tag-new {
  display: inline-block;
  padding: 2px 7px;
  border-radius: 999px;
  background: var(--orange);
  color: var(--orange-on);
  font-family: var(--mono);
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  vertical-align: 2px;
}

/* The last group sits away from the subscribe field above it rather than
   carrying an inline margin — the deploy CSP discards style="..." attributes,
   so an inline nudge here works everywhere except production. */
.bio-links-spaced { margin-top: 20px; }

/* ------------------------------------------------------------ subscribe box
   ONE PILL, with the button inside it at the end.
   It was two stacked full-width pills — a field and a button, 132px of form in
   a column of 60px rows — which matched the shape of a row without matching its
   weight. A single control that happens to contain a submit reads as one of the
   list; two controls read as a form that has been given rounded corners.

   The FORM carries the border and shadow now, and the input inside it is
   stripped bare: any border of its own would draw a second outline a few pixels
   inside the first, which is the thing that makes an input look bolted in
   rather than built in.

   The honeypot is absolutely positioned (see .hp in main.css) so it does not
   take a column in this flex row. */
.bio-signup .signup {
  display: flex; align-items: center; gap: 8px;
  max-width: none; min-height: 60px;
  padding: 6px 6px 6px 20px;
  background: var(--paper);
  border: 1.5px solid var(--ink);
  border-radius: 999px;
  box-shadow: 0 2px 0 var(--ink);
}
/* Focus moves to the WHOLE pill, because the visible control is the pill — a
   ring around the bare input inside would sit in mid-air. */
.bio-signup .signup:focus-within {
  outline: 2px solid var(--orange); outline-offset: 2px;
}
.bio-signup .signup input {
  flex: 1 1 auto; min-width: 0;
  background: none; border: 0; padding: 0; box-shadow: none;
  color: var(--ink); font: inherit; font-size: 16px;
}
/* 16px is not a style choice: iOS Safari zooms the page in on a focused field
   under 16px and does not zoom back out. */
.bio-signup .signup input:focus { outline: none; }
.bio-signup .signup input::placeholder { color: var(--muted); }
.bio-signup .signup button {
  flex: 0 0 auto;
  padding: 11px 18px; border-radius: 999px; border: 0;
  background: var(--orange); color: var(--orange-on);
  font: inherit; font-size: 13.5px; font-weight: 700; letter-spacing: 0.01em;
  cursor: pointer; white-space: nowrap;
}
.bio-signup .signup button:hover,
.bio-signup .signup button:focus-visible { background: var(--ink); color: var(--paper); }
.bio-signup .form-note { display: none; }

/* --------------------------------------------------------------- masthead
   The newsletter's NAME was rendered as a .bio-rule — 10px, uppercase, letter-
   spaced, muted — which is the divider style, the same one the word "brands"
   gets. A masthead and a category label are different jobs, and at 10px muted
   the name could not do either. */
.bio-masthead { margin: 30px 0 12px; text-align: center; }
.bio-masthead h2 {
  font-size: 21px; line-height: 1.2; letter-spacing: -0.02em;
  margin: 0 0 6px; color: var(--ink);
}
.bio-masthead p {
  margin: 0 auto; max-width: 32ch;
  font-size: 13.5px; line-height: 1.5; color: var(--muted);
}

/* ------------------------------------------------------------------- tipping
   Same row shape as every other link, in the accent, because it is the one
   thing on the page that asks for money rather than attention and should not
   be mistaken for another channel. */
.bio-links a.tip {
  background: var(--orange); border-color: var(--orange); color: var(--orange-on);
}
/* NO OPACITY HERE — see the note above .bio-links a.primary. Dimming this line
   to .82 blends it into the orange fill at 3.85:1, under the 4.5 an 11px line
   needs. This rule was added with the featured tip row and reintroduced the
   exact bug, at the exact ratio, that the comment fifteen lines up already
   records as fixed. Second rank comes from size and weight, not from spending
   contrast. */
.bio-links a.tip .meta { color: var(--orange-on); }
.bio-links a.tip:hover,
.bio-links a.tip:focus-visible {
  background: var(--ink); border-color: var(--ink); color: var(--paper);
}
.bio-links a.tip:hover .meta,
.bio-links a.tip:focus-visible .meta { color: var(--paper); }

/* The featured row sits above the channels at the SAME 12px the list uses
   internally. It had 22, to hold it apart as its own thing — but it is the only
   orange row on a page of paper ones, so the separating was already done, and
   all the extra gap bought was one join in the stack that did not match the
   others. An irregular rhythm with no reason behind it is what reads as
   unfinished. */
.bio-featured { margin-bottom: 12px; }
