/* ═══════════════════════════════════════════════════════════════════════
   Penguin Bacon Studios — site styles

   One committed dark world. There is no light theme and that is a choice,
   not an omission: the brand is a polar night, the splash screen the app
   launches with is #0b1f33, and a daylight counterpart would be a second
   identity to design and keep in step. Every colour is therefore painted
   explicitly rather than inherited from the viewer's settings.

   Colours are the app's own tokens wherever the app has one, so the site
   and the game are visibly the same product. See penguindoku/src/styles.scss.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── fonts ─────────────────────────────────────────────────────────────
   Self-hosted. A studio whose whole pitch is "no trackers, no network
   calls" should not open by asking Google for its typefaces. Both are
   the latin subset, 50 KB for the pair.

   Luckiest Guy is the BRAND face and is rationed: the wordmark, page
   headlines, game titles, and the three numbers on the landing page.
   Nothing else. Outfit carries everything that is actually read.        */
@font-face {
  font-family: 'Luckiest Guy';
  src: url('fonts/luckiest-guy.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Outfit';
  src: url('fonts/outfit.woff2') format('woff2');
  font-weight: 300 700;      /* variable */
  font-style: normal;
  font-display: swap;
}

:root {
  /* surfaces — --night is the exact splash background, so the browser and
     the app launch on the same colour */
  --deep: #060f1e;
  --night: #0b1f33;
  --shelf: #12293f;
  --raised: #17364f;
  --line: rgba(157, 180, 199, 0.18);
  --line-bright: rgba(79, 195, 247, 0.28);

  /* ink — the app's --text / --text-dim / --text-faint */
  --snow: #e8f3fb;
  --fog: #9db4c7;
  --faint: #6b8399;

  /* aurora */
  --mint: #4be3b0;
  --violet: #a177ff;
  --cyan: #4fc3f7;          /* the app's --accent */
  --bacon: #ff8a5b;

  --shell: 1140px;
  --radius: 18px;
  --radius-sm: 12px;

  color-scheme: dark;
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--deep);
  color: var(--snow);
  font: 300 17px/1.7 Outfit, system-ui, -apple-system, 'Segoe UI', sans-serif;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; }

a { color: var(--cyan); }
a:hover { color: var(--mint); }

:focus-visible {
  outline: 2px solid var(--cyan);
  outline-offset: 3px;
  border-radius: 4px;
}

/* Skip link — visible only once focused, which is the one time it matters. */
.skip {
  position: absolute;
  left: 12px;
  top: -60px;
  z-index: 200;
  background: var(--mint);
  color: #062418;
  font-weight: 600;
  padding: 12px 18px;
  border-radius: var(--radius-sm);
  text-decoration: none;
  transition: top 0.15s;
}
.skip:focus { top: 12px; }

.shell {
  max-width: var(--shell);
  margin: 0 auto;
  padding: 0 28px;
}

/* ── penguins ──────────────────────────────────────────────────────────
   The Illustrator exports carry ~138 global .stN class names and generic
   gradient ids, so inlining two of them would have the second overwrite
   the first's styles. They stay as images, exactly as the app keeps them.
   The art is portrait; the aspect ratio comes from each file's viewBox
   and the caller sizes the box.                                          */
.peng {
  display: block;
  background-repeat: no-repeat;
  background-position: center bottom;
  background-size: contain;
  aspect-ratio: var(--ar, 1);
}
.peng.eat        { --ar: 0.654; background-image: url('art/penguin-bacon-eat.svg'); }
.peng.feast      { --ar: 1;     background-image: url('art/penguin-bacon-feast.svg'); }
.peng.chef       { --ar: 0.986; background-image: url('art/penguin-bacon-chef.svg'); }
.peng.architect  { --ar: 0.806; background-image: url('art/penguin-bacon-architect.svg'); }
.peng.delivery   { --ar: 1;     background-image: url('art/penguin-bacon-delivery.svg'); }
.peng.standeat   { --ar: 0.671; background-image: url('art/penguin-bacon-stand-eat.svg'); }
.peng.stuffed    { --ar: 0.910; background-image: url('art/penguin-bacon-stuffed.svg'); }

/* ── aurora ────────────────────────────────────────────────────────────
   Three blurred ribbons behind the top of the page. Penguindoku already
   draws an aurora behind the board (features/game/stage.ts), so the site
   and the game open on the same sky.                                     */
.aurora {
  position: absolute;
  inset: 0 0 auto;
  height: 660px;
  overflow: hidden;
  pointer-events: none;
  z-index: 0;
}
.aurora i {
  position: absolute;
  display: block;
  border-radius: 50%;
  filter: blur(74px);
}
.aurora i:nth-child(1) {
  width: 860px; height: 310px; left: -140px; top: -100px;
  background: var(--mint); opacity: 0.5;
  animation: drift 24s ease-in-out infinite alternate;
}
.aurora i:nth-child(2) {
  width: 720px; height: 270px; left: 34%; top: -150px;
  background: var(--violet); opacity: 0.44;
  animation: drift 29s ease-in-out infinite alternate-reverse;
}
.aurora i:nth-child(3) {
  width: 660px; height: 240px; right: -110px; top: 0;
  background: var(--cyan); opacity: 0.38;
  animation: drift 20s ease-in-out infinite alternate;
}
@keyframes drift {
  from { transform: translate3d(0, 0, 0) scaleX(1); }
  to   { transform: translate3d(66px, 28px, 0) scaleX(1.18); }
}
.stars {
  position: absolute;
  inset: 0 0 auto;
  height: 660px;
  pointer-events: none;
  opacity: 0.65;
  z-index: 0;
  background-image:
    radial-gradient(1.6px 1.6px at 12% 18%, #fff 50%, transparent),
    radial-gradient(1.4px 1.4px at 78% 12%, #fff 50%, transparent),
    radial-gradient(1.8px 1.8px at 44% 30%, #fff 50%, transparent),
    radial-gradient(1.3px 1.3px at 64% 41%, #fff 50%, transparent),
    radial-gradient(1.5px 1.5px at 28% 47%, #fff 50%, transparent),
    radial-gradient(1.2px 1.2px at 90% 34%, #fff 50%, transparent),
    radial-gradient(1.4px 1.4px at 7% 38%, #fff 50%, transparent),
    radial-gradient(1.1px 1.1px at 55% 9%, #fff 50%, transparent);
}
/* The aurora is the page's only ambient motion. Under reduced motion it
   holds still rather than disappearing — the sky is the design, the
   drifting is the flourish. */
@media (prefers-reduced-motion: reduce) {
  .aurora i { animation: none; }
}

/* everything that is not sky sits above it */
.above { position: relative; z-index: 1; }

/* ── wordmark ──────────────────────────────────────────────────────────
   The app's splash stacks PENGUIN / BACON / STUDIOS on three lines in
   Luckiest Guy at line-height 1.02, art above, all sized off the widest
   line so the three read as one block (tools/generate-splash.mjs). The
   site reuses that lockup rather than setting the name on one line, so
   launching the app and opening the site show the same mark.            */
.wordmark {
  display: flex;
  align-items: center;
  gap: 12px;
  text-decoration: none;
  color: var(--snow);
}
.wordmark .peng { width: 42px; flex: none; background-position: center; }
.wordmark .stack {
  font: 400 15px/1.02 'Luckiest Guy', system-ui, sans-serif;
  letter-spacing: 0.035em;
  text-transform: uppercase;
  display: grid;
}
.wordmark:hover .stack { color: var(--mint); }

/* the big centred version, in the footer */
.lockup {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;
  text-align: center;
}
.lockup .peng { width: 118px; }
.lockup .stack {
  font: 400 clamp(30px, 5vw, 44px)/1.02 'Luckiest Guy', system-ui, sans-serif;
  letter-spacing: 0.025em;
  text-transform: uppercase;
  color: var(--snow);
  display: grid;
}

/* ── header ────────────────────────────────────────────────────────── */
.top {
  display: flex;
  align-items: center;
  gap: 20px;
  /* padding-block, never the `padding: 22px 0` shorthand. These classes are
     always used alongside .shell, which supplies the horizontal padding, and
     a shorthand here wins on the cascade and zeroes it -- which took the side
     gutters off every section and ran the text into the screen edge on a
     phone. */
  padding-block: 22px;
}
.top nav {
  margin-left: auto;
  display: flex;
  gap: 28px;
  align-items: center;
}
.top nav a {
  font: 400 16px/1 Outfit, sans-serif;
  color: var(--fog);
  text-decoration: none;
}
.top nav a:hover { color: var(--mint); }
.top nav a[aria-current='page'] { color: var(--snow); }

/* ── type scale ────────────────────────────────────────────────────── */
h1, h2, h3, h4 { text-wrap: balance; margin: 0; }

.display {
  font: 400 clamp(38px, 6.2vw, 74px)/0.98 'Luckiest Guy', system-ui, sans-serif;
  letter-spacing: 0.005em;
  text-shadow: 0 0 38px rgba(75, 227, 176, 0.3);
}
.display em { font-style: normal; color: var(--mint); }

.title {
  font: 400 clamp(28px, 3.6vw, 42px)/1.05 'Luckiest Guy', system-ui, sans-serif;
}

/* Section headings are Outfit, not the brand face — the brand face stops
   being a signal if every heading wears it. */
.sect-head {
  font: 500 14px/1 Outfit, sans-serif;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--faint);
  margin: 0 0 24px;
}

.lede {
  font: 300 clamp(18px, 2vw, 21px)/1.65 Outfit, sans-serif;
  color: var(--fog);
  max-width: 46ch;
}

.prose { max-width: 64ch; }
.prose h2 {
  font: 600 26px/1.3 Outfit, sans-serif;
  color: var(--snow);
  margin: 46px 0 12px;
}
.prose h3 {
  font: 600 19px/1.4 Outfit, sans-serif;
  color: var(--snow);
  margin: 32px 0 8px;
}
.prose p { margin: 0 0 18px; color: var(--fog); }
.prose ul { margin: 0 0 18px; padding-left: 22px; color: var(--fog); }
.prose li { margin-bottom: 9px; }
.prose li::marker { color: var(--cyan); }
.prose strong { color: var(--snow); font-weight: 600; }

/* ── buttons ───────────────────────────────────────────────────────── */
.btns { display: flex; gap: 14px; flex-wrap: wrap; }
.btn {
  font: 500 16px/1 Outfit, sans-serif;
  border-radius: var(--radius-sm);
  padding: 15px 26px;
  text-decoration: none;
  border: 1.5px solid transparent;
  display: inline-block;
}
.btn.primary {
  background: var(--mint);
  color: #062418;
  font-weight: 600;
  box-shadow: 0 0 32px rgba(75, 227, 176, 0.36);
}
.btn.primary:hover { background: #6ceec2; color: #062418; }
.btn.ghost { border-color: rgba(157, 180, 199, 0.4); color: var(--snow); }
.btn.ghost:hover { border-color: var(--mint); color: var(--mint); }

/* ── hero ──────────────────────────────────────────────────────────── */
.hero {
  display: grid;
  grid-template-columns: 1.08fr 0.92fr;
  gap: 40px;
  align-items: end;
  padding-block: 40px 0;
}
.hero .copy { padding-bottom: 60px; }
.hero .display { margin-bottom: 22px; }
.hero .lede { margin: 0 0 32px; }

/* the snow ridge the hero penguin stands on */
.ridge {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: flex-end;
  min-height: 350px;
}
.ridge .peng {
  width: 100%;
  max-width: 300px;
  position: relative;
  z-index: 2;
  filter: drop-shadow(0 0 44px rgba(79, 195, 247, 0.32));
}
.ridge::after {
  content: '';
  position: absolute;
  left: -16%; right: -16%; bottom: -1px;
  height: 124px;
  z-index: 1;
  background: linear-gradient(180deg, var(--raised), var(--night));
  border-radius: 50% 50% 0 0 / 72% 72% 0 0;
}

/* ── the one-game shelf ────────────────────────────────────────────── */
.band { padding-block: 66px; border-top: 1px solid var(--line); }
.band:first-of-type { border-top: 0; }

.shelf { display: grid; grid-template-columns: 1.1fr 1fr; gap: 34px; align-items: center; }

.gcard {
  background: linear-gradient(160deg, rgba(23, 54, 79, 0.92), rgba(11, 31, 51, 0.92));
  border: 1px solid var(--line-bright);
  border-radius: var(--radius);
  padding: 30px 32px;
  display: flex;
  gap: 26px;
  align-items: center;
}
.gcard .peng { width: 132px; flex: none; }
.gcard .title { margin-bottom: 8px; }
.gcard p { font: 300 16px/1.6 Outfit, sans-serif; color: var(--fog); margin: 0 0 16px; }

.pill {
  display: inline-block;
  font: 600 12px/1 Outfit, sans-serif;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--bacon);
  border: 1px solid rgba(255, 138, 91, 0.45);
  border-radius: 999px;
  padding: 8px 14px;
}

/* Three numbers, in the brand face because they are the argument.
   Not a card kit — a plain list with a rule between rows. */
.stats { display: grid; gap: 2px; }
.stat {
  display: flex;
  gap: 18px;
  align-items: baseline;
  padding: 16px 0;
  border-bottom: 1px solid var(--line);
}
.stat:last-child { border-bottom: 0; }
.stat b {
  font: 400 34px/1 'Luckiest Guy', system-ui, sans-serif;
  min-width: 104px;
  font-variant-numeric: tabular-nums;
  color: var(--cyan);
}
.stat:nth-child(2) b { color: var(--mint); }
.stat:nth-child(3) b { color: var(--violet); }
.stat span { font: 300 16px/1.5 Outfit, sans-serif; color: var(--fog); }

/* ── ruled out ─────────────────────────────────────────────────────────
   The × is the game's own mark for a square a player has eliminated. The
   things the studio has ruled out wear the same mark. Not a card grid —
   these are one list, so they share one container and one rhythm.        */
.ruled {
  display: grid;
  /* 280px rather than 230px so the six items land in three columns and fill
     two complete rows. At 230px they made four columns and left the second
     row two-thirds empty. */
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}
/* Direct child only. `.ruled div` also matched the wrapper inside each cell,
   which turned it into a flex row and stood the label and its sentence side
   by side in two very narrow columns. */
.ruled > div {
  background: var(--night);
  padding: 22px 24px;
  display: flex;
  gap: 14px;
  align-items: flex-start;
}
.ruled .x {
  flex: none;
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  border-radius: 7px;
  background: rgba(255, 138, 91, 0.14);
  color: var(--bacon);
  font: 600 15px/1 Outfit, sans-serif;
}
.ruled b { font: 600 16.5px/1.35 Outfit, sans-serif; color: var(--snow); display: block; }
.ruled p { font: 300 15px/1.55 Outfit, sans-serif; color: var(--fog); margin: 5px 0 0; }

/* ── the board ─────────────────────────────────────────────────────────
   A real, solved 6×6 Penguindoku position: one penguin per colony, none
   sharing a row or column, and none touching — not even at a corner.
   Colony colours are the app's --region-0..5.                            */
.board {
  --c0: #3d7fbf; --c1: #c88a35; --c2: #4f9d55;
  --c3: #9159bd; --c4: #d0605a; --c5: #2ba39b;
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  width: 100%;
  max-width: 380px;
  aspect-ratio: 1;
  border-radius: var(--radius-sm);
  overflow: hidden;
  border: 2px solid rgba(0, 0, 0, 0.35);
}
.board span {
  position: relative;
  border: 0.5px solid rgba(255, 255, 255, 0.09);
}
.board .r0 { background: var(--c0); }
.board .r1 { background: var(--c1); }
.board .r2 { background: var(--c2); }
.board .r3 { background: var(--c3); }
.board .r4 { background: var(--c4); }
.board .r5 { background: var(--c5); }
.board .p::after {
  content: '';
  position: absolute;
  inset: 11%;
  background: url('art/penguin-bacon-eat.svg') center/contain no-repeat;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.45));
}
.board-note {
  font: 300 14.5px/1.6 Outfit, sans-serif;
  color: var(--faint);
  margin: 14px 0 0;
  max-width: 40ch;
}

/* ── rules list, on the game page ──────────────────────────────────────
   Deliberately not numbered. The four rules all apply at once — they are
   not steps to work through in order, and numbering them would say they
   were.                                                                  */
.rules { display: grid; gap: 16px; margin: 0; padding: 0; list-style: none; }
/* Indent-and-absolute, NOT a grid or flex row. Each item is a bold lead-in
   followed by a bare text node, and a grid container makes those two things
   two separate items: the sentence gets placed in the next cell along, which
   is the 26px marker column, and wraps one word per line. Keeping the li in
   normal flow keeps its inline content in one run. */
.rules li {
  position: relative;
  padding-left: 26px;
  font: 300 17px/1.6 Outfit, sans-serif;
  color: var(--fog);
}
.rules li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.6em;
  width: 11px;
  height: 11px;
  border-radius: 3px;
  background: var(--cyan);
  transform: rotate(45deg);
}
.rules li:nth-child(2)::before { background: var(--mint); }
.rules li:nth-child(3)::before { background: var(--violet); }
.rules li:nth-child(4)::before { background: var(--bacon); }
.rules strong { color: var(--snow); font-weight: 600; }

/* ── footer ────────────────────────────────────────────────────────── */
.foot {
  border-top: 1px solid var(--line);
  background: var(--night);
  padding: 56px 0 40px;
  margin-top: 40px;
}
.foot .lockup { margin-bottom: 34px; }
.foot .links {
  display: flex;
  flex-wrap: wrap;
  gap: 14px 30px;
  justify-content: center;
  font: 400 15px/1 Outfit, sans-serif;
  margin-bottom: 22px;
}
.foot .links a { color: var(--fog); text-decoration: none; }
.foot .links a:hover { color: var(--mint); }
.foot .fine {
  text-align: center;
  font: 300 14px/1.6 Outfit, sans-serif;
  color: var(--faint);
  margin: 0;
}

/* ── page header for the inner pages ───────────────────────────────── */
.page-head { padding-block: 34px 26px; }
.page-head .title { margin-bottom: 14px; }
.page-head p { font: 300 18px/1.6 Outfit, sans-serif; color: var(--fog); margin: 0; max-width: 56ch; }
.updated {
  font: 400 13px/1 Outfit, sans-serif;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--faint);
  margin: 0 0 18px;
}

/* ── responsive ────────────────────────────────────────────────────── */
@media (max-width: 900px) {
  .hero { grid-template-columns: 1fr; gap: 10px; }
  .hero .copy { padding-bottom: 20px; }
  .shelf { grid-template-columns: 1fr; }
  .gcard { flex-direction: column; align-items: flex-start; }
  .gcard .peng { width: 108px; }
}
@media (max-width: 640px) {
  .shell { padding: 0 20px; }
  .top nav { gap: 18px; }
  .top nav a { font-size: 15px; }
  .band { padding-block: 48px; }
  .ridge { min-height: 280px; }
}
@media (max-width: 460px) {
  .top { flex-wrap: wrap; }
  .top nav { margin-left: 0; width: 100%; }
}
