/* Poplu, a Peppi move · Cikku.ai "Sunrise Arcade" tokens (DESIGN-TOKENS.md, 2026-08-08).
   Shared across the sign-in, onboarding and dashboard screens. Creatives keep the CLIENT's brand. */
:root {
  --canvas: #FFF6E3; --canvas-2: #FFD9A8; --card: #FFFCF3;
  --ink: #2A1A0F; --ink-soft: #4A3626;
  --yolk: #FFC421; --tangerine: #FF7A1A; --flame: #FF4B2B; --teal: #00B8A9; --teal-bg: #E4FBF8;
  /* Flame and tangerine are fills. As small text on cream they read at about 3:1 and 2.5:1, so
     words in those colours use the deeper ink of each (about 6:1 on canvas and card, 4.8:1 on
     canvas-2), and words on a flame fill are ink (5:1; cream on it was 3.1:1). */
  --flame-ink: #B02E18; --tangerine-ink: #9A4400; --on-flame: var(--ink);
  --line: 3px solid var(--ink); --line-thin: 2px solid var(--ink); --hairline: 1.5px solid var(--ink);
  --shadow-sm: 3px 3px 0 0 var(--ink); --shadow-md: 5px 5px 0 0 var(--ink); --shadow-lg: 8px 8px 0 0 var(--ink);
  --shadow-teal: 4px 4px 0 0 var(--teal); --shadow-press: 2px 2px 0 0 var(--ink);
  --font-display: 'Baloo 2', ui-rounded, 'Segoe UI Rounded', sans-serif;
  --font-body: 'Nunito Sans', ui-sans-serif, system-ui, sans-serif;
  --font-hud: 'Press Start 2P', monospace;
  --font-num: 'Chivo Mono', ui-monospace, monospace;
  --spring: cubic-bezier(0.34, 1.56, 0.64, 1);
  --radius: 16px;
}
* { box-sizing: border-box; margin: 0; }
body {
  background: var(--canvas); color: var(--ink);
  font-family: var(--font-body); font-size: 16px; line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}
.mono { font-family: var(--font-num); }
.hud { font-family: var(--font-hud); font-size: 10px; letter-spacing: 0.06em; text-transform: uppercase; line-height: 1.5; }
a { color: var(--flame-ink); font-weight: 700; }

/* The wordmark is drawn, not typed: yolk and cream letters on a flame extrusion, both ringed
   in ink, with Peppi's contrail looping off the end. Two copies of data-word make the depth
   behind the real text, so the heading still reads as one word (the "/ ''" keeps screen
   readers from saying it three times). */
.wordmark { position: relative; isolation: isolate; display: inline-block; white-space: nowrap;
  font-family: var(--font-display); font-weight: 800; letter-spacing: 0.005em; line-height: 1.05;
  color: var(--yolk); padding: 0 1.45em 0.12em 0;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 60'%3E%3Cmask id='m'%3E%3Cpath d='M4 50C18 20 44 6 58 16C70 25 60 42 49 35C38 28 52 8 72 8C80 8 86 11 89 15' fill='none' stroke='%23fff' stroke-width='9' stroke-linecap='round' pathLength='1' stroke-dasharray='1' stroke-dashoffset='1'%3E%3Canimate attributeName='stroke-dashoffset' values='1;0' dur='.7s' begin='.25s' calcMode='spline' keyTimes='0;1' keySplines='.35 0 .25 1' fill='freeze'/%3E%3C/path%3E%3C/mask%3E%3Cpath d='M4 50C18 20 44 6 58 16C70 25 60 42 49 35C38 28 52 8 72 8C80 8 86 11 89 15' fill='none' stroke='%232A1A0F' stroke-width='4' stroke-linecap='round' stroke-dasharray='.5 8' mask='url(%23m)'/%3E%3Ccircle cx='90' cy='17' r='0' fill='%23FFFCF3' stroke='%232A1A0F' stroke-width='3.5'%3E%3Canimate attributeName='r' values='0;8.5;7' keyTimes='0;.6;1' begin='.9s' dur='.3s' fill='freeze'/%3E%3C/circle%3E%3C/svg%3E")
    no-repeat right 0 top -0.05em / 1.4em auto; }
/* The contrail draws itself once as the page opens (SMIL inside the image, so it needs no script),
   then the puff pops. Reduced motion gets the finished trail. */
@media (prefers-reduced-motion: reduce) {
  .wordmark { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 60'%3E%3Cpath d='M4 50C18 20 44 6 58 16C70 25 60 42 49 35C38 28 52 8 72 8C80 8 86 11 89 15' fill='none' stroke='%232A1A0F' stroke-width='4' stroke-linecap='round' stroke-dasharray='.5 8'/%3E%3Ccircle cx='90' cy='17' r='7' fill='%23FFFCF3' stroke='%232A1A0F' stroke-width='3.5'%3E%3C/circle%3E%3C/svg%3E"); }
}
.wordmark > span:first-child { color: var(--card); }
.wordmark::before, .wordmark::after { content: attr(data-word); content: attr(data-word) / "";
  position: absolute; left: 0; top: 0; z-index: -1; -webkit-text-stroke: 0.16em var(--ink); paint-order: stroke fill; }
.wordmark::before { color: var(--flame); transform: translate(0.04em, 0.045em); }
.wordmark::after { color: var(--ink); z-index: -2; transform: translate(0.09em, 0.1em); }
.tag { font-size: 13px; font-weight: 600; color: var(--ink-soft); }
.brand { display: flex; align-items: center; gap: 16px; }
.mascot { width: 76px; height: 76px; object-fit: cover; border: 4px solid var(--ink); background: var(--card);
  border-radius: 42% 58% 55% 45% / 48% 42% 58% 52%; box-shadow: var(--shadow-md); padding: 3px; flex: none; }

/* ---------- centred pages (sign in, onboarding) ---------- */
.shell { max-width: 760px; margin: 0 auto; padding: 48px 24px 80px; }
.shell.wide { max-width: 1080px; }
.shell h1 { font-size: 48px; }
.shell h2 { font-family: var(--font-display); font-weight: 700; font-size: 26px; line-height: 1.2; margin-bottom: 6px; }
.lede { font-size: 17px; line-height: 1.55; color: var(--ink-soft); margin-top: 14px; }

.panel { background: var(--card); border: var(--line); border-radius: var(--radius); padding: 22px; margin-top: 24px; box-shadow: var(--shadow-md); }
.panel + .panel { margin-top: 20px; }
.panel.done { border-color: var(--teal); box-shadow: 5px 5px 0 0 var(--teal); background: var(--teal-bg); }

label { display: block; font-size: 13.5px; font-weight: 700; margin: 14px 0 6px; }
/* A label is a line and its hint is the line under it. Run together they read as one
   sentence ("Invite code Poplu is invite-only"), which is how a field ends up looking
   like a paragraph nobody reads. */
label .hint { display: block; font-weight: 400; color: var(--ink-soft);
  font-size: 13px; line-height: 1.5; margin-top: 3px; }

/* The one small-label role, in the body face. Press Start 2P below 9px is a texture, not
   text: it was carrying field names, table headings and warnings at 7px. */
.label { font-size: 11px; font-weight: 800; letter-spacing: 0.07em; text-transform: uppercase;
  color: var(--ink-soft); line-height: 1.4; }
input[type=text], input[type=email], input[type=password], input[type=url], textarea, select {
  width: 100%; font-family: inherit; font-size: 15px; line-height: 1.45;
  padding: 10px 12px; border: var(--line-thin); border-radius: 8px;
  background: #fff; color: var(--ink);
}
textarea { resize: vertical; min-height: 96px; }
input:focus, textarea:focus, select:focus { outline: none; border-color: var(--teal); box-shadow: var(--shadow-teal); }

button { font-family: inherit; cursor: pointer; }
/* Where the keyboard is, on every page: the thick ink line the whole look is drawn with, set
   off the control so it reads on any fill. The browser's own ring was thin and blue on cream,
   and gone wherever a rule reset the control. Fields keep their teal glow (above). */
:focus-visible { outline: 3px solid var(--ink); outline-offset: 3px; }
input[type=checkbox]:focus-visible, input[type=radio]:focus-visible { outline: 3px solid var(--ink); outline-offset: 2px; }
.btn {
  font-family: var(--font-display); font-size: 16px; font-weight: 700; line-height: 1; padding: 13px 22px; border-radius: 999px;
  background: var(--yolk); color: var(--ink); border: var(--line); box-shadow: var(--shadow-md);
  text-decoration: none; display: inline-block;
  transition: transform .15s var(--spring), box-shadow .15s, background .15s;
}
.btn:hover { transform: translate(-1px, -1px); box-shadow: var(--shadow-teal); }
.btn:active { transform: translate(3px, 3px); box-shadow: var(--shadow-press); }
.btn[disabled] { opacity: 0.5; cursor: not-allowed; transform: none; box-shadow: var(--shadow-press); }
.btn.ghost { background: var(--card); }
.btn.small { font-size: 14px; padding: 10px 16px; box-shadow: var(--shadow-sm); }
.row { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; margin-top: 18px; }
.spacer { flex: 1; }

.note { font-size: 13.5px; color: var(--ink-soft); line-height: 1.55; margin-top: 10px; }
.error { background: var(--flame); border: var(--line-thin); color: var(--on-flame); font-weight: 600;
  padding: 10px 13px; border-radius: 8px; font-size: 13.5px; margin-top: 14px; line-height: 1.5; box-shadow: var(--shadow-sm); }
.ok { background: var(--teal-bg); border: var(--line-thin); color: var(--ink); font-weight: 600;
  padding: 10px 13px; border-radius: 8px; font-size: 13.5px; margin-top: 14px; box-shadow: var(--shadow-sm); }
[hidden] { display: none !important; }

.chips { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; }
/* Chips carry real words — a platform, a status, a file, an event — so they are set in the
   body face. At 8px in the arcade face they were shapes you had to lean in to decode. */
.chip { font-size: 11.5px; font-weight: 700; letter-spacing: 0.02em; padding: 6px 10px;
  border-radius: 999px; border: var(--line-thin); color: var(--ink); background: var(--card); line-height: 1.3; }
.chip.ready { background: var(--teal); }
.chip.failed { background: var(--flame); color: var(--on-flame); }
.chip.pending { background: var(--yolk); }
.chip.x { cursor: pointer; }

.drop { border: 3px dashed var(--ink); border-radius: var(--radius); padding: 26px; text-align: center; background: #fff;
  color: var(--ink-soft); font-size: 14px; font-weight: 600; cursor: pointer; margin-top: 12px; }
.drop.over { border-style: solid; border-color: var(--teal); background: var(--teal-bg); color: var(--ink); }
/* Setup's photo quest (public/photoquest.js): bonus loot, the photos found on their pages. */
.snap-grid { list-style: none; padding: 0; margin: 10px 0 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(76px, 1fr)); gap: 8px; }
.snap-grid li { position: relative; aspect-ratio: 1; border: var(--line-thin); border-radius: 8px; overflow: hidden; background: #fff; }
.snap-grid img { width: 100%; height: 100%; object-fit: cover; display: block; }
.snap-grid .snap-from { position: absolute; left: 4px; bottom: 4px; font-size: 10px; font-weight: 700; padding: 1px 6px;
  border-radius: 999px; background: var(--card); border: 1.5px solid var(--ink); }
.snap-grid .snap-drop { position: absolute; right: 4px; top: 4px; width: 26px; height: 26px; border-radius: 50%;
  border: 1.5px solid var(--ink); background: var(--card); font-weight: 800; line-height: 1; cursor: pointer; padding: 0; }

/* the "we are building your profile" screen */
.progress { display: flex; gap: 12px; align-items: center; margin-top: 20px; font-size: 15px; font-weight: 600; }
.dot { width: 12px; height: 12px; border-radius: 50%; background: var(--tangerine); border: 2px solid var(--ink); animation: pulse 1.1s ease-in-out infinite; }
@keyframes pulse { 0%, 100% { opacity: 0.35; transform: scale(0.85); } 50% { opacity: 1; transform: scale(1); } }
@media (prefers-reduced-motion: reduce) { .dot { animation: none; } .btn, .btn:hover, .btn:active { transition: none; transform: none; } }

/* The one tick box on the signup form: agreeing to the terms. */
label.agree { display: flex; align-items: flex-start; gap: 10px; font-weight: 600; margin-top: 18px; }
label.agree input { flex: none; width: 20px; height: 20px; margin: 1px 0 0; accent-color: var(--teal); }
label.agree a, .note.legal a, .legal a { color: inherit; }
.note.legal { margin-top: 18px; }

/* --- /terms and /privacy: long reading, so the body face at a reading size ------ */
.doc h2 { margin-top: 28px; }
.doc h3 { font-family: var(--font-display); font-weight: 700; font-size: 19px; margin: 26px 0 8px; }
.doc p, .doc li { font-size: 15.5px; line-height: 1.65; }
.doc p + p { margin-top: 10px; }
.doc ul { padding-left: 20px; display: grid; gap: 6px; }
.doc a { color: inherit; }
.doc .brand a { display: block; }

/* --- the boot screen: Peppi covers a page until its first load is in (boot.js) ------ */
.boot { position: fixed; inset: 0; z-index: 100; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 18px; padding: 24px; text-align: center; background: linear-gradient(180deg, var(--canvas) 0%, var(--canvas-2) 100%);
  transition: opacity 0.35s ease, visibility 0.35s; }
.boot.done { opacity: 0; visibility: hidden; pointer-events: none; }
.boot-peppi { position: relative; width: 168px; height: 168px; border: 4px solid var(--ink); background: var(--card);
  border-radius: 42% 58% 55% 45% / 48% 42% 58% 52%; box-shadow: var(--shadow-lg); overflow: hidden; }
/* The loop is drawn on white; multiply lays it onto the card's cream so no white box shows. */
.boot-peppi img, .boot-peppi video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; mix-blend-mode: multiply; }
.boot-peppi img { animation: boot-hop 1.2s var(--spring) infinite; transform-origin: 50% 90%; }
.boot-peppi video { opacity: 0; transition: opacity 0.2s ease; }
.boot-peppi video.playing { opacity: 1; }
.boot-peppi video.playing + img { visibility: hidden; }
/* A business with another bird (starter.js): <html data-bird> is set before first paint
   (starter-first.js), so that bird hops in the card from the start. The loop is Peppi's alone. */
html[data-bird] .boot-peppi img, html[data-bird] .boot-peppi video { display: none; }
html[data-bird] .boot-peppi::after { content: ""; position: absolute; inset: 0; background: center / cover no-repeat;
  animation: boot-hop 1.2s var(--spring) infinite; transform-origin: 50% 90%; }
html[data-bird="rozi"] .boot-peppi::after { background-image: url(/starters/rozi.webp); }
html[data-bird="cikku"] .boot-peppi::after { background-image: url(/starters/cikku.webp); }
html[data-bird="zeppi"] .boot-peppi::after { background-image: url(/starters/zeppi.webp); }
.boot .wordmark { font-size: 44px; }
.boot-bar { width: 200px; height: 14px; border: var(--line-thin); border-radius: 999px; background: var(--card); overflow: hidden; box-shadow: var(--shadow-sm); }
.boot-bar span { display: block; height: 100%; width: 40%; border-radius: 999px; background: var(--tangerine);
  border-right: var(--line-thin); animation: boot-slide 1.3s ease-in-out infinite; }
.boot-line { color: var(--ink-soft); min-height: 1.5em; }
@keyframes boot-hop { 0%, 100% { transform: translateY(0) scale(1, 1); } 30% { transform: translateY(-9px) scale(0.97, 1.03); }
  55% { transform: translateY(0) scale(1.03, 0.97); } 70% { transform: translateY(0) scale(1, 1); } }
@keyframes boot-slide { 0% { transform: translateX(-100%); } 100% { transform: translateX(250%); } }
@media (prefers-reduced-motion: reduce) {
  .boot, .boot-peppi video.playing { transition: none; }
  .boot-peppi img, .boot-peppi::after, .boot-bar span { animation: none; }
  .boot-peppi video { display: none; }
  .boot-bar span { width: 100%; opacity: 0.5; }
}

/* Motion turned off in the phone's or computer's settings: off everywhere, not rule by rule.
   Every page loads this sheet, so this one block covers what app.css, evolve.css and the pages'
   own sheets animate, the business's bird hopping over a post included. Each animation and
   transition still ends where it would have (a stamp still shows, a drawer still opens), it
   just gets there at once. The rules above that say `animation: none` stay as they are. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; animation-delay: 0s !important;
    transition-duration: 0.01ms !important; transition-delay: 0s !important; scroll-behavior: auto !important;
  }
}

/* The plan picker (start.html card step, Settings): three cards to tap, one picked. */
.plan-pick { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 12px; margin-top: 12px; }
.plan-opt { text-align: left; font: inherit; color: var(--ink); background: #fff; border: var(--line-thin); border-radius: 12px;
  padding: 14px 14px 12px; cursor: pointer; box-shadow: var(--shadow-sm); position: relative; transition: transform .12s var(--spring); }
.plan-opt:hover { transform: translate(-1px, -1px); }
.plan-opt[aria-checked="true"] { background: var(--teal-bg); border-color: var(--ink); box-shadow: 4px 4px 0 0 var(--teal); }
.plan-opt b { display: block; font-family: var(--font-display); font-size: 20px; line-height: 1.1; }
.plan-opt .plan-price { display: block; font-family: var(--font-num); font-size: 15px; font-weight: 700; margin-top: 6px; }
.plan-opt .plan-vat { display: block; font-size: 12px; color: var(--ink-soft); margin-top: 1px; }
.plan-opt .plan-sum { display: block; font-size: 13px; color: var(--ink-soft); line-height: 1.45; margin-top: 8px; }
.plan-opt .plan-best { position: absolute; top: -10px; right: 10px; background: var(--yolk); border: var(--hairline); border-radius: 999px;
  font-size: 11px; font-weight: 700; padding: 2px 8px; }
@media (prefers-reduced-motion: reduce) { .plan-opt { transition: none; } .plan-opt:hover { transform: none; } }

/* "You on Google" on the setup screen (start.js): the listing found, and whether it is theirs. */
.gplace.mine { border-color: var(--teal); box-shadow: 5px 5px 0 0 var(--teal); }
.gplace-card { display: grid; gap: 4px; margin-top: 12px; padding: 14px 16px; background: #fff;
  border: var(--line-thin); border-radius: 12px; overflow-wrap: anywhere; }
.gplace-card b { font-size: 17px; }
.gplace-card .meta { font-size: 13.5px; color: var(--ink-soft); line-height: 1.45; }
.gplace-card a.meta { color: var(--ink); font-weight: 600; }
