/* fwiends — an operating system for one egg.
   White ground, because the teaser is shot on white and the art carries its own
   near-black; the internet-native register comes from the chrome on top of it,
   not from going dark. Monospace throughout: it is the browser's own material,
   and it reads technical and native at the same time without trying. */
:root{
  --paper:#FCFAFB; --art:#050308;
  --ink:#14090f; --body:#3c2e35; --dim:#6b5962; --faint:#8d7b85;
  --rule:#e7dae0; --rule-lit:#d0b6c3;
  --accent:#c9265c; --hot:#F14F85;
  --mono:"JetBrains Mono","Menlo",ui-monospace,monospace;
  --bar:34px;
}
*{box-sizing:border-box}
/* Selecting text on the page paints pink, and `mark` uses the same treatment —
   so a highlighted phrase reads as text someone left selected rather than as a
   highlighter pen. */
::selection{background:var(--hot);color:#fff}
mark{background:var(--hot);color:#fff;padding:.06em 0;border-radius:1px}
html{background:var(--paper)}
/* The scatter reaches past the desk; never let that make a sideways scrollbar. */
body{overflow-x:hidden}
body{
  margin:0;color:var(--body);font-family:var(--mono);font-size:1.02rem;line-height:1.62;
  -webkit-font-smoothing:antialiased;
  background-color:var(--paper);
  /* The desk. A faint grid, so the windows sit on a surface. */
  background-image:
    linear-gradient(rgba(201,38,92,.055) 1px, transparent 1px),
    linear-gradient(90deg, rgba(201,38,92,.055) 1px, transparent 1px);
  background-size:26px 26px;
}

/* ---- menu bar ---------------------------------------------------------- */
.menubar{
  position:sticky;top:0;z-index:50;height:var(--bar);
  background:var(--ink);color:#e8dbe1;
  display:flex;align-items:center;padding:0 1rem;
  font-size:.78rem;letter-spacing:.1em;text-transform:uppercase;
}
.menubar .brand{color:var(--hot);font-weight:800;letter-spacing:.14em}
.menubar .right{margin-left:auto;color:#8e7b84;letter-spacing:.08em;
                display:flex;gap:.7rem;align-items:center}
.menubar .lamp{color:var(--hot)}
/* The bar is sticky, so this is the only ask on screen for the whole scroll.
   Boxed rather than underlined, so it reads as a tray control and not as body
   text that happens to be a link. */
.menubar .mb-follow{
  color:#fff;border:1px solid rgba(252,193,211,.42);border-radius:999px;
  padding:.16rem .6rem;letter-spacing:.1em;
  transition:background .12s steps(1),border-color .12s steps(1);
}
.menubar .mb-follow:hover{background:var(--hot);border-color:var(--hot)}
/* The ask outranks the status line: when the bar runs out of room the status
   goes and the CTA stays. */
@media(max-width:700px){ .menubar .status{display:none} }

/* ---- desk -------------------------------------------------------------- */
.desk{position:relative;max-width:880px;margin:0 auto;padding:1.9rem 1.1rem 3.4rem;
      display:flex;flex-direction:column;gap:1.5rem}

/* Charms strewn in the margins, some running under the windows so they read as
   things lying on the desk rather than as a border. They sit below the windows
   in the stack; anything the layout covers is meant to be covered. */
.stickers{position:absolute;inset:0;z-index:0;pointer-events:none}
/* The white die-cut border is baked into each sprite on its own pixel grid, so
   all that is left here is the shadow that lifts it off the paper. drop-shadow
   follows the sticker's silhouette, which a box-shadow could not. */
.stickers img{position:absolute;height:auto;image-rendering:pixelated;
              filter:drop-shadow(2px 3px 2px rgba(20,9,15,.28))}
@media(max-width:1180px){ .stickers{display:none} }

/* Windows sit at different offsets and widths so the column reads as things
   dropped on a desk rather than a stack of blocks. All of it is margin inside
   the container — nothing bleeds out, so no window can cause a sideways
   scrollbar — and it all collapses below the breakpoint. */
.off-a{margin-right:2.8rem}
.off-b{margin-left:1.7rem}
.off-c{margin-left:3.6rem;margin-right:.9rem}
.off-d{margin-right:3.2rem}
.off-e{margin-left:2.3rem}
@media(max-width:760px){
  .off-a,.off-b,.off-c,.off-d,.off-e{margin-left:0;margin-right:0}
}

/* ---- windows ----------------------------------------------------------- */
.win{position:relative;z-index:1;background:#fff;border:1.5px solid var(--ink);border-radius:6px;
     box-shadow:4px 4px 0 rgba(20,9,15,.9);overflow:hidden}
.win.tight{max-width:560px}
.tb{display:flex;align-items:center;gap:.7rem;
    background:var(--hot);color:#fff;border-bottom:1.5px solid var(--ink);
    padding:.4rem .7rem;font-size:.77rem;letter-spacing:.07em}
/* In a real system only the focused window is coloured. Letting every window
   run a pink bar turns the accent into wallpaper — and the sections that are
   deliberately quiet (a locked folder, a text file) should look quiet. */
.win.bg > .tb{background:#f2e7ec;color:var(--dim)}
.win.bg > .tb .name{color:var(--ink)}
.tb .name{font-weight:700}
.tb .ctl{margin-left:auto;opacity:.85;letter-spacing:.16em}
.wb{padding:1.15rem}

/* ---- the wordmark ------------------------------------------------------ */
.mark{margin:0;font-size:3.7rem;line-height:1;font-weight:800;color:var(--ink);
      letter-spacing:-.045em}
@keyframes blink{0%,50%{opacity:1}50.01%,100%{opacity:0}}
.cur{color:var(--hot);font-weight:400;animation:blink 1.06s steps(1) infinite}
@media(prefers-reduced-motion:reduce){ .cur{animation:none} }

/* A boot line under the wordmark: the same dotted leader the spec panel uses,
   so the page reads as one system reporting on itself. */
.boot{display:flex;align-items:baseline;gap:.55rem;margin:.9rem 0 0;max-width:25rem;
      font-size:.86rem;letter-spacing:.04em}
.boot .k{color:var(--faint);text-transform:uppercase;letter-spacing:.12em;flex:0 0 auto}
.boot .v{color:var(--accent);flex:0 0 auto}

/* Three lanes, one sentence each, divided so none leans on the one before. */
.lanes{margin-top:1.05rem}
.lanes p{margin:0;padding:.58rem 0;color:var(--ink);font-size:1.12rem;line-height:1.5}
.lanes p + p{border-top:1px solid var(--rule)}

/* ---- stage heading ------------------------------------------------------
   A path in a title bar names a file; it does not announce a stage. The stage
   says what it is inside the window, where the eye actually lands. */
.stagehead{margin:0 0 .95rem}
.stagehead .num{display:block;font-size:.77rem;letter-spacing:.18em;text-transform:uppercase;
                color:var(--faint)}
.stagehead .name{margin:.18rem 0 0;font-size:2.2rem;line-height:1;font-weight:800;
                 color:var(--ink);letter-spacing:-.03em}
.lock .stagehead .name{color:var(--rule-lit)}

/* ---- button ------------------------------------------------------------
   A pill with a heavy outline and the arrow at the trailing end, where it
   points at what happens next. Hover fills from the left in eight steps rather
   than easing, so it reads as a bar loading instead of a colour fading. */
.pillbtn{
  position:relative;overflow:hidden;flex:0 0 auto;
  display:inline-flex;align-items:center;gap:1rem;
  padding:.62rem .95rem;background:#fff;border:3px solid var(--ink);border-radius:999px;
  text-decoration:none;
}
.pillbtn::before{
  content:"";position:absolute;inset:0;background:var(--hot);
  transform:scaleX(0);transform-origin:left center;transition:transform .26s steps(8);
}
.pillbtn:hover::before,.pillbtn:focus-visible::before{transform:scaleX(1)}
.pillbtn .label,.pillbtn .tip{position:relative;z-index:1}
.pillbtn .label{color:var(--ink);font-weight:700;font-size:.72rem;letter-spacing:.04em;
                transition:color .26s steps(8)}
.pillbtn .tip{display:flex;color:var(--hot);transition:color .26s steps(8),transform .1s steps(2)}
.pillbtn:hover .label,.pillbtn:focus-visible .label{color:#fff}
.pillbtn:hover .tip,.pillbtn:focus-visible .tip{color:#fff;transform:translateX(3px)}
.pillbtn:active::before{background:var(--accent)}
@media(prefers-reduced-motion:reduce){
  .pillbtn::before,.pillbtn .label,.pillbtn .tip{transition:none}
}

/* ---- stage cards -------------------------------------------------------
   One window, a row of portrait cards. Each card is a labelled panel on the
   art's own ground with a dotted field over it; the unrevealed stages show an
   outlined character where the creature will be. */
/* Perspective lives on the row, so each card turns in the same space rather
   than in one of its own — a shared vanishing point instead of four. */
.cards{display:flex;gap:1rem;perspective:1100px}
.card{position:relative;flex:1 1 0;min-width:0;margin:0;aspect-ratio:3/4;overflow:hidden;
      background:var(--art);border:1.5px solid var(--ink);border-radius:4px;
      display:flex;flex-direction:column;padding:.75rem;
      transition:transform .28s cubic-bezier(.2,.7,.3,1),box-shadow .28s ease}
.card:hover{
  transform:rotateX(5deg) rotateY(-8deg) translateZ(16px);
  box-shadow:14px 18px 26px rgba(20,9,15,.24);
}
@media(prefers-reduced-motion:reduce){ .card{transition:none} .card:hover{transform:none} }
.card .meta{position:relative;z-index:1;font-size:.64rem;letter-spacing:.15em;
            text-transform:uppercase;color:var(--hot);line-height:1.75}
.card .meta b{display:block;color:#fff;font-weight:700}
/* Outlined, not filled — the shape of the stage without its substance. */
.card .glyph{position:relative;z-index:1;margin-top:auto;text-align:center;
             font-size:5rem;font-weight:800;line-height:.9;color:transparent;
             -webkit-text-stroke:2px var(--hot);user-select:none}
.card .shot{position:relative;z-index:1;margin-top:auto}
.card .shot img{display:block;width:100%;height:auto}
.card.open .meta b{color:var(--hot)}

.cardsfoot{display:flex;align-items:center;gap:1.2rem;flex-wrap:wrap;margin-top:1.1rem}
.lockmsg{margin:0;font-size:.9rem;color:var(--dim)}

/* ---- readme ------------------------------------------------------------- */
.readme{display:grid;grid-template-columns:1fr 1fr;gap:1.8rem;align-items:start}
.readme .lanes{margin-top:0}

/* ---- the egg ----------------------------------------------------------- */
.egg{display:grid;grid-template-columns:284px 1fr;gap:1.4rem;align-items:start}
.art{background:var(--art);padding:.5rem;border:1.5px solid var(--ink);border-radius:4px;
     line-height:0;width:100%;max-width:284px}
.art img{display:block;width:100%;height:auto}
.desc{margin:0 0 1.15rem;color:var(--body);max-width:42ch}

/* Real numbers, printed like a product label. Nothing here is invented. */
.spec{margin:0;font-size:.86rem;letter-spacing:.02em}
.spec div{display:flex;gap:.5rem;align-items:baseline;padding:.2rem 0}
.spec dt{color:var(--faint);text-transform:uppercase;letter-spacing:.1em;flex:0 0 auto}
.lead{flex:1 1 auto;border-bottom:1px dotted var(--rule-lit);transform:translateY(-3px)}
.spec dd{margin:0;color:var(--ink);flex:0 0 auto}
.spec dd em{font-style:normal;color:var(--accent)}

/* ---- terminal ---------------------------------------------------------
   A window whose body is the field itself. Live rather than a GIF: every
   column falls at its own speed, so no loop of a sane length is seamless. */
.term .wb{background:var(--art);padding:0;display:flex;align-items:stretch;gap:0}
.term canvas{display:block;flex:1 1 auto;height:210px;min-width:0}
.tty{flex:0 0 auto;margin:0;padding:1.15rem 1.3rem;font-family:var(--mono);
     font-size:.84rem;line-height:1.75;color:var(--hot);white-space:pre;
     border-left:1px solid rgba(252,193,211,.16)}
@media(max-width:620px){
  .term .wb{flex-direction:column}
  .term canvas{height:170px;width:100%}
  .tty{border-left:none;border-top:1px solid rgba(252,193,211,.16)}
}

/* ---- prose ------------------------------------------------------------- */
.prose p{margin:0 0 .95rem;max-width:62ch}
.prose p:last-child{margin-bottom:0}
.prose b{color:var(--ink)}
.ask{margin-top:1.4rem!important;font-size:1.45rem;line-height:1.34;color:var(--ink);
     font-weight:700;letter-spacing:-.02em;max-width:24ch}
.ask em{font-style:normal;color:var(--accent)}
a{color:var(--accent);text-decoration:none;border-bottom:1px solid var(--rule-lit)}
a:hover{border-bottom-color:var(--accent)}

/* ---- overlapping windows ----------------------------------------------
   A second window sitting behind the last one, the way a desktop stacks them.
   The front window is narrowed so the one behind it stays visible on the right
   rather than being fully covered. Below the breakpoint they simply stack. */
.stack{position:relative;z-index:1}
.stack .front{position:relative;z-index:2;width:76%}
.stack .pack{position:absolute;z-index:1;right:0;top:-2.6rem;width:290px}
.stack .pack .wb{padding:.55rem}
.stack .pack img{display:block;width:100%;height:auto;border-radius:3px}
@media(max-width:860px){
  .stack{display:flex;flex-direction:column;gap:1.5rem}
  .stack .front{width:100%}
  .stack .pack{position:static;width:100%;max-width:340px;order:2}
}

/* ---- status bar -------------------------------------------------------- */
.statusbar{position:relative;z-index:1;display:flex;gap:1.3rem;flex-wrap:wrap;align-items:center;
           font-size:.78rem;letter-spacing:.08em;text-transform:uppercase;color:var(--faint);
           border-top:1.5px solid var(--ink);padding-top:.8rem;margin-top:.4rem}
.statusbar a{border-bottom:none;color:var(--dim)}
.statusbar .motto{margin-left:auto;color:var(--accent);font-weight:700}
.statusbar a:hover{color:var(--accent)}

@media(max-width:760px){
  .cards{flex-wrap:wrap}
  .card{flex:1 1 calc(50% - .5rem)}
  .readme{grid-template-columns:1fr;gap:1.2rem}
}
@media(max-width:640px){
  .desk{padding:1.3rem .8rem 2.6rem;gap:1.2rem}
  .win.inset{margin-left:0}
  .mark{font-size:2.5rem}
  .egg{grid-template-columns:1fr;gap:1rem}
  .art{max-width:100%}
}
