/* ═══════════════════════════════════════════════════════════
   krein.id — one screen, no page scroll.
   Type: Bitcount (dot-matrix display) + Courier Prime (UI/body).
   Momo Trust Display is reserved for the logo wordmark only.
   ═══════════════════════════════════════════════════════════ */

@font-face{font-family:'Momo';src:url('../../fonts/momo-trust-display-v2-latin-regular.woff2')format('woff2');font-weight:400;font-display:swap}
@font-face{font-family:'Bitcount';src:url('../../fonts/bitcount-prop-single-200.woff2')format('woff2');font-weight:200;font-display:swap}
@font-face{font-family:'Bitcount';src:url('../../fonts/bitcount-prop-single-300.woff2')format('woff2');font-weight:300;font-display:swap}
@font-face{font-family:'Bitcount';src:url('../../fonts/bitcount-prop-single-400.woff2')format('woff2');font-weight:400;font-display:swap}
@font-face{font-family:'Bitcount';src:url('../../fonts/bitcount-prop-single-500.woff2')format('woff2');font-weight:500;font-display:swap}
@font-face{font-family:'Bitcount';src:url('../../fonts/bitcount-prop-single-600.woff2')format('woff2');font-weight:600;font-display:swap}
@font-face{font-family:'Courier Prime';src:url('../../fonts/courier-prime-400.woff2')format('woff2');font-weight:400;font-display:swap}
@font-face{font-family:'Courier Prime';src:url('../../fonts/courier-prime-700.woff2')format('woff2');font-weight:700;font-display:swap}

:root{
  --bg:#EAEAEA;
  --surface:#DEDEDE;         /* recessed panels: image frames, hovers */
  --ink:#0D0D0D;
  --mute:#67675F;            /* meets AA against --bg at body size */
  --line:#D3D3D3;
  --line-2:#BDBDBD;
  /* Two oranges, on purpose.
     --accent is the bright one, for MARKS: rules, dots, squares, ticks.
     It measures 2.56:1 on the background, so it must never carry words.
     --accent-ink is the same hue darkened to 5.01:1 — that one is for the
     few places the colour has to be readable text. */
  --accent:#F06B00;
  --accent-ink:#A34800;
  --brand:#C86515;           /* the logo mark and wordmark */

  --mono:'Courier Prime',ui-monospace,'SFMono-Regular',Menlo,monospace;
  --dots:'Bitcount','Courier Prime',monospace;

  --logo-h:26px;             /* mark size; the wordmark is locked to it below */

  /* Portfolio cards. The layout slot is always --slot wide so nothing
     reflows as the highlight moves; only the frame inside it grows, from
     --narrow (portrait) to --wide (landscape). Height never changes. */
  --narrow:.78;
  --wide:1.34;
  /* Height leads and the slot follows, so the rail stays filled; the vw
     term keeps the widened centre card from crowding out its neighbours. */
  --card-h:clamp(190px,min(56vh,43vw),520px);
  --slot:calc(var(--card-h) * var(--wide));

  --edge:clamp(14px,3vw,44px);
  --gap:clamp(12px,1.8vw,26px);
  --bar:clamp(52px,7.4vh,68px);
  --snap:.22s cubic-bezier(.2,.9,.3,1);
}

*{box-sizing:border-box}

html,body{height:100%;margin:0;overflow:hidden;overscroll-behavior:none}

body{
  background:var(--bg);
  color:var(--ink);
  font-family:var(--mono);
  font-size:14px;
  line-height:1.65;
  -webkit-font-smoothing:antialiased;
  -webkit-tap-highlight-color:transparent;
}

a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:0;padding:0;cursor:pointer}
img{display:block}
::selection{background:var(--accent);color:#fff}

/* thin scrollbars in the accent, for the two panes that do scroll */
.scroll,.sheet-scroll{scrollbar-width:thin;scrollbar-color:var(--accent) transparent}
.scroll::-webkit-scrollbar,.sheet-scroll::-webkit-scrollbar{width:6px;height:6px}
.scroll::-webkit-scrollbar-thumb,.sheet-scroll::-webkit-scrollbar-thumb{background:var(--accent)}
.scroll::-webkit-scrollbar-track,.sheet-scroll::-webkit-scrollbar-track{background:transparent}

:focus-visible{outline:2px solid var(--accent);outline-offset:2px}

.dot{color:var(--accent);font-style:normal}

/* Readable by crawlers and screen readers, not shown on screen. Used for
   the page heading and business details, which the logo represents
   visually. Clipped rather than display:none, which would hide it from
   assistive technology too. */
.sr-only{
  position:absolute;width:1px;height:1px;
  margin:-1px;padding:0;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);
  white-space:nowrap;border:0;
}

/* ── BACKGROUND GRID ──────────────────────────────────── */

/* Painted by grid.js. Sits under everything and never takes a click. */
#grid{
  position:fixed;inset:0;z-index:0;
  pointer-events:none;
  display:block;
}

/* ── SHELL ────────────────────────────────────────────── */

.shell{position:relative;z-index:1;height:100dvh;display:flex;flex-direction:column}

/* Solid, so the background grid stops at the chrome instead of running
   underneath the navigation. */
.bar{
  position:relative;z-index:2;background:var(--bg);
  flex:none;height:var(--bar);padding:0 var(--edge);
  display:grid;grid-template-columns:1fr auto 1fr;align-items:center;
  border-bottom:1px solid var(--line);
}

.logo{justify-self:start;display:flex;align-items:center;gap:.34em}
.logo-mark{width:var(--logo-h);height:var(--logo-h);flex:none}

/* Wordmark carries the brand terracotta, and its drawn height is matched
   to the mark: "krein.id" has no descenders, so its inked height measures
   0.8125 of the font size — dividing by that makes both exactly as tall. */
.logo-type{
  font-family:'Momo',var(--mono);
  font-size:calc(var(--logo-h) / .8125);
  line-height:1;letter-spacing:.005em;color:var(--brand);
}
.logo-type .dot{color:var(--brand)}   /* the logo keeps terracotta throughout */

.tabs{justify-self:center;display:flex;align-items:center;gap:clamp(14px,2.4vw,30px)}

.tab{
  position:relative;padding:5px 0;
  font-size:clamp(12px,1.25vw,14px);letter-spacing:.02em;
  color:var(--mute);white-space:nowrap;transition:color var(--snap);
}
.tab:hover{color:var(--ink)}
.tab::after{
  content:'';position:absolute;left:0;right:0;bottom:0;height:2px;
  background:var(--accent);transform:scaleX(0);transform-origin:left;
  transition:transform var(--snap);
}
.tab.is-on{color:var(--ink)}
.tab.is-on::after{transform:scaleX(1)}
/* a hint of the underline on hover, so the colour reads as interactive */
.tab:hover::after{transform:scaleX(1);opacity:.34}
.tab.is-on:hover::after{opacity:1}

.bar-end{justify-self:end;display:flex;align-items:center;gap:10px}

.lang{
  font-size:10px;letter-spacing:.16em;color:var(--mute);
  border:1px solid var(--line);padding:5px 7px;transition:border-color var(--snap),color var(--snap);
}
.lang:hover{color:var(--ink);border-color:var(--accent)}
/* 10px text, so the readable orange rather than the bright one */
.lang .is-on{color:var(--accent-ink)}
.lang-sep{font-style:normal;opacity:.3;margin:0 3px}

/* CTA — solid block, square corners */
.cta{
  display:inline-flex;align-items:center;gap:9px;
  padding:8px 15px;background:var(--ink);color:var(--bg);
  font-size:11px;letter-spacing:.14em;text-transform:uppercase;white-space:nowrap;
  transition:opacity var(--snap),transform var(--snap);
}
.cta::after{content:'';width:5px;height:5px;background:var(--accent)}
.cta:hover{opacity:.84}
.cta:active{transform:translateY(1px)}
.cta-lg{padding:13px 24px;font-size:12px}

/* ── STAGE / PANELS ───────────────────────────────────── */

.stage{flex:1;position:relative;min-height:0}

.panel{
  position:absolute;inset:0;display:flex;flex-direction:column;min-height:0;
  opacity:0;pointer-events:none;transition:opacity .18s linear;
}
.panel.is-on{opacity:1;pointer-events:auto}
.panel[hidden]{display:none}

.scroll{flex:1;min-height:0;overflow-y:auto;padding:var(--edge);scrollbar-width:thin}

/* ── PORTF. — infinite horizontal rail ────────────────── */

.rail-wrap{flex:1;min-height:0;position:relative;display:flex}

/* perspective turns the per-card rotateY from app.js into a drum that
   rolls away behind the centre; without it they would just look skewed */
.rail{
  flex:1;min-height:0;display:flex;align-items:center;overflow:hidden;
  cursor:grab;user-select:none;-webkit-user-select:none;touch-action:pan-y;
  perspective:1400px;perspective-origin:50% 50%;
}

/* Arrows — a way through for anyone who does not think to swipe.
   Deliberately NOT backdrop-filter. That property forces the whole
   3D-transformed rail behind it onto a different rasterisation path, and
   every card rendered as a blank box. A translucent white fill reads the
   same here, because the background behind it is a flat colour. */
.nav{
  position:absolute;top:50%;transform:translateY(-50%);z-index:3;
  width:clamp(34px,4.4vw,46px);height:clamp(34px,4.4vw,46px);
  display:flex;align-items:center;justify-content:center;
  border-radius:50%;
  background:rgba(255,255,255,.66);
  box-shadow:0 0 0 1px rgba(255,255,255,.8), 0 3px 14px rgba(0,0,0,.12);
  color:var(--ink);
  transition:background-color var(--snap),box-shadow var(--snap),opacity var(--snap);
}
.nav svg{width:56%;height:56%;fill:none;stroke:currentColor;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round}
.nav:hover{background:rgba(255,255,255,.88);box-shadow:0 0 0 1px var(--accent), 0 3px 14px rgba(0,0,0,.14)}
.nav:active{transform:translateY(-50%) scale(.94)}
.nav-prev{left:clamp(8px,1.6vw,20px)}
.nav-next{right:clamp(8px,1.6vw,20px)}
.rail.is-drag{cursor:grabbing}
.rail:focus-visible{outline:1px solid var(--accent);outline-offset:-2px}

/* Kill the browser's native drag-the-picture behaviour. Without this it
   hijacks the pointer stream, so the swipe stalls AND no click ever fires. */
.rail a,.rail img{-webkit-user-drag:none;user-drag:none}

.rail-track{
  display:flex;align-items:center;gap:var(--gap);padding:0 var(--gap);
  transform-style:preserve-3d;
}

/* Fixed-width slot: the highlight changes the frame inside, never the
   layout, so offsets stay valid while the rail moves.
   width / opacity / blur are driven per-frame from app.js — no CSS
   transition here, or it would fight the drag. */
/* Deliberately NOT preserve-3d or backface-visibility here. A card has no
   3D children of its own — only .rail-track needs to keep its children in
   space. Promoting each card to a 3D context made it rasterise into a
   layer that a late-arriving photo failed to invalidate, so cards stayed
   blank until something else forced a repaint. */
.card{
  flex:none;width:var(--slot);display:block;
}

/* Height is constant; width is what marks the highlighted card. The
   starting value is the portrait one, so the rail looks right even
   before the first paint. */
.card-fr{
  position:relative;
  height:var(--card-h);
  width:calc(var(--card-h) * var(--narrow));
  margin:0 auto;
  background:var(--surface);overflow:hidden;
  border:1px solid var(--line);
}
.card-fr img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transition:transform .5s cubic-bezier(.2,.9,.3,1)}
.card:hover .card-fr img{transform:scale(1.035)}

/* corner ticks — technical framing, in the accent so the crop marks read */
.card-fr::before,.card-fr::after{
  content:'';position:absolute;width:8px;height:8px;pointer-events:none;z-index:1;
  border-color:var(--accent);opacity:.9;
}
.card-fr::before{top:7px;left:7px;border-top:1px solid;border-left:1px solid}
.card-fr::after{bottom:7px;right:7px;border-bottom:1px solid;border-right:1px solid}

.card-no{
  position:absolute;top:8px;right:9px;z-index:1;
  font-family:var(--dots);font-size:13px;color:var(--accent);
}

/* the caption of the centred card gets a small leading rule */
.card-nm{position:relative}

/* Tracks the frame width so the caption stays flush with the photo edge. */
.card-meta{
  display:flex;flex-direction:column;gap:2px;
  width:calc(var(--card-h) * var(--narrow));
  margin:10px auto 0;
}
.card-nm{font-size:13px;letter-spacing:.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.card-sub{font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--mute);white-space:nowrap}

/* placeholder when an image file is missing */
.ph::after{display:none}
.ph::before{
  content:attr(data-ph);inset:0;width:auto;height:auto;border:0;
  display:flex;align-items:center;justify-content:center;padding:14px;
  text-align:center;font-family:var(--dots);font-size:15px;
  color:var(--mute);opacity:1;line-height:1.4;
}

/* ── STRIP / READOUT ──────────────────────────────────── */

/* Same as the top bar: the footer band sits in front of the grid. */
.strip{
  position:relative;z-index:2;background:var(--bg);
  flex:none;padding:clamp(12px,2vh,20px) var(--edge);
  border-top:1px solid var(--line);
  display:flex;align-items:center;justify-content:space-between;gap:var(--gap);
}

.readout{display:flex;align-items:baseline;gap:clamp(18px,3.4vw,50px);min-width:0;overflow:hidden}

/* Each stat is tagged with a small orange square rather than being tinted:
   the numbers stay black and legible, the colour still reads as a system. */
.rd{position:relative;display:flex;flex-direction:column;gap:1px;line-height:1.1;padding-top:9px}
.rd::before{content:'';position:absolute;top:0;left:0;width:5px;height:5px;background:var(--accent)}
.rd b{font-family:var(--dots);font-weight:600;font-size:clamp(22px,2.8vw,34px);letter-spacing:.02em}
.rd span{font-size:9px;letter-spacing:.16em;text-transform:uppercase;color:var(--mute);white-space:nowrap}
/* First stat is the headline figure. It uses the bright orange by explicit
   request; at 2.56:1 that is below the readable threshold, so no other
   text is allowed to follow it. */
.rd:first-child::before{width:100%;max-width:26px}
.rd:first-child b{color:var(--accent)}

.tick{
  position:relative;z-index:2;background:var(--bg);
  flex:none;margin:0;padding:0 var(--edge) clamp(9px,1.5vh,15px);
  font-size:9px;letter-spacing:.18em;text-transform:uppercase;color:var(--mute);
  display:flex;align-items:center;gap:8px;
}
/* blinking cursor-square: the line reads as a live status readout */
.tick::before{content:'';flex:none;width:4px;height:4px;background:var(--accent);animation:blip 2.6s steps(1,end) infinite}
@keyframes blip{0%,62%{opacity:1}63%,100%{opacity:.18}}

/* ── PROJ. — every project, grouped by year ───────────── */

.years{max-width:1280px;margin:0 auto}

.yr + .yr{margin-top:clamp(28px,5vh,54px)}

.yr-hd{
  display:flex;align-items:baseline;gap:12px;
  padding-bottom:10px;margin-bottom:clamp(12px,2vh,20px);
  border-bottom:1px solid var(--line);
}
.yr-hd h2{
  margin:0;font-family:var(--dots);font-weight:500;
  font-size:clamp(17px,2.2vw,24px);letter-spacing:.03em;
}
.yr-hd span{
  font-size:9px;letter-spacing:.18em;color:var(--mute);
  border:1px solid var(--accent);padding:2px 6px;
}

/* Steam-style shelf: portrait tiles, roomy gaps, softly rounded. */
.tiles{
  display:grid;
  grid-template-columns:repeat(auto-fill,minmax(clamp(122px,15vw,178px),1fr));
  gap:clamp(12px,1.6vw,22px);
}

.tile{display:block}

.tile-fr{
  position:relative;width:100%;aspect-ratio:3/4;
  background:var(--surface);overflow:hidden;
  border-radius:6px;
  box-shadow:0 0 0 1px var(--line);
  transition:box-shadow var(--snap),transform var(--snap);
}
.tile-fr img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transition:transform .5s cubic-bezier(.2,.9,.3,1)}
.tile:hover .tile-fr{box-shadow:0 0 0 1px var(--accent);transform:translateY(-3px)}
.tile:hover .tile-fr img{transform:scale(1.05)}

.tile-nm{
  display:block;margin-top:9px;font-size:12px;line-height:1.35;
  transition:color var(--snap);
}
.tile:hover .tile-nm{color:var(--accent-ink)}

.tile-sub{
  display:block;margin-top:2px;
  font-size:9px;letter-spacing:.12em;text-transform:uppercase;color:var(--mute);
}

/* ── OUR CLIENTS ──────────────────────────────────────── */

/* Column count and tile size are computed in app.js from the panel's real
   dimensions, so the grid fills whatever screen it is on rather than
   guessing from viewport width. Both arrive as custom properties. */
/* Centred with auto margins on a flex parent rather than min-height:100%.
   The percentage version overflowed its padding by a hair, which reserved
   a scrollbar the content never needed and pushed the grid off centre.
   Auto margins also keep the grid reachable if it ever grows taller than
   the panel, which align-items:center would not. */
/* both-edges keeps the scrollbar gutter symmetric, so the grid reads as
   centred on the screen rather than pushed left by the bar's width. */
#p-clients .scroll{display:flex;scrollbar-gutter:stable both-edges}

.grid{
  display:grid;
  grid-template-columns:repeat(var(--cols,6), var(--tile,120px));
  gap:10px;
  margin:auto;
}

.cell{
  position:relative;
  aspect-ratio:1/1;
  padding:0;border:0;border-radius:3px;
  background:var(--surface);
  box-shadow:0 0 0 1px var(--line);
  overflow:hidden;cursor:pointer;
  transition:box-shadow var(--snap);
}
.cell:hover,.cell.is-open{box-shadow:0 0 0 1px var(--accent)}

.cell img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}

/* The darkening plate is its own layer, so bringing it in never touches
   the logo underneath. */
.cell::after{
  content:'';position:absolute;inset:0;
  background:rgba(13,13,13,.8);
  opacity:0;transition:opacity var(--snap);
  pointer-events:none;
}

/* Two captions that cross-fade, rather than one that travels. The corner
   one labels the tile at rest; the centred one takes over on the plate.
   Both size off the tile, so they hold up at any grid size. */
.cell-nm,.cell-big{
  position:absolute;z-index:1;
  font-family:var(--mono);
  line-height:1.2;letter-spacing:.02em;
  transition:opacity var(--snap);
  pointer-events:none;
}

/* Corner caption. Black or white depending on how bright that corner of
   the logo is — decided per logo at build time, not guessed here. */
.cell-nm{
  left:6px;right:6px;bottom:5px;
  text-align:left;
  font-size:clamp(7px,calc(var(--tile,120px) * .075),11px);
  color:var(--ink);
}
.cell.is-dark .cell-nm{color:#fff}
.cell.is-bare .cell-nm{color:var(--mute)}

/* Centred caption, only present while the plate is down. */
.cell-big{
  inset:0;padding:0 8%;
  display:flex;align-items:center;justify-content:center;
  text-align:center;
  font-size:clamp(10px,calc(var(--tile,120px) * .115),17px);
  font-weight:700;color:#fff;
  opacity:0;
}

.cell:hover::after,.cell.is-open::after{opacity:1}
.cell:hover .cell-nm,.cell.is-open .cell-nm{opacity:0}
.cell:hover .cell-big,.cell.is-open .cell-big{opacity:1}

/* A phone leaves :hover stuck on the last tile it touched, which would
   fight the tap-to-toggle. Hover only applies where it is real. */
@media (hover: none){
  .cell:hover::after{opacity:0}
  .cell:hover .cell-nm{opacity:1}
  .cell:hover .cell-big{opacity:0}
  .cell.is-open::after{opacity:1}
  .cell.is-open .cell-nm{opacity:0}
  .cell.is-open .cell-big{opacity:1}
}

/* ── BOUT.US ──────────────────────────────────────────── */

.about{max-width:1080px;margin:0 auto;padding-bottom:clamp(20px,4vh,40px)}
.about p{margin:0 0 13px;max-width:64ch;color:var(--mute)}
.about p strong{color:var(--ink);font-weight:400}

/* The opening line is the loudest thing on the panel, so it carries the
   dot-matrix face. A heavy, tightly set dot-matrix turns to mush in a long
   sentence — this one is three words, so it can take the weight. The rule
   above it is the same 22px accent mark that opens a project sheet. */
.about-tag{
  position:relative;margin:0 0 clamp(14px,2.4vh,22px);padding-top:14px;
  max-width:none;color:var(--ink);
  font-family:var(--dots);font-weight:500;
  font-size:clamp(22px,4.4vw,46px);line-height:1.12;letter-spacing:.05em;
}
.about-tag::before{content:'';position:absolute;top:0;left:0;width:22px;height:2px;background:var(--accent)}

/* Standfirst: ink rather than grey, and a size up, so it reads as the
   sentence the rest of the panel explains. */
.about-lead{
  margin:0;max-width:58ch;color:var(--ink);
  font-size:clamp(14px,1.35vw,17px);line-height:1.75;
}

.about-sec{
  margin-top:clamp(26px,4.6vh,50px);
  padding-top:clamp(18px,3vh,30px);
  border-top:1px solid var(--line);
}

/* Same small capitalised label as the contact blocks below, so the panel
   reads as one document rather than two. */
.about-hd{
  position:relative;margin:0 0 clamp(12px,2vh,18px);padding-top:9px;
  font-size:10px;font-weight:400;letter-spacing:.18em;text-transform:uppercase;color:var(--mute);
}
.about-hd::before{content:'';position:absolute;top:0;left:0;width:14px;height:1px;background:var(--accent)}

/* A panel rather than a ruled section. It spans the full content column —
   its left edge lines up with the opening line — and its fill is the page
   colour, which is what puts it in front of the drifting dot field instead
   of letting the dots run through the words. Same trick the top bar and
   the footer strip use; here it is simply given a corner. */
.about-card{
  border-top:0;
  background:var(--bg);
  border-radius:40px;
  box-shadow:0 0 0 1px var(--line);
  padding:clamp(22px,3.4vh,34px) clamp(20px,3vw,40px) clamp(24px,3.8vh,38px);
}

/* The five reasons. No numerals: the accent square already tags every
   statistic and fact on this site, so reusing it keeps one vocabulary. */
.why{list-style:none;margin:0;padding:0;
  display:grid;grid-template-columns:repeat(auto-fit,minmax(238px,1fr));
  gap:clamp(16px,2.4vw,30px) clamp(18px,3vw,44px);
}
.why-it{position:relative;padding-left:15px}
.why-it::before{content:'';position:absolute;top:6px;left:0;width:5px;height:5px;background:var(--accent)}
.why-it h3{margin:0 0 5px;font-size:12.5px;font-weight:400;letter-spacing:.03em;color:var(--ink);line-height:1.4}
.why-it p{margin:0;max-width:44ch;font-size:12.5px;line-height:1.7}

.meta{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(168px,1fr));gap:var(--gap);
  margin-top:clamp(24px,4.4vh,44px);padding-top:clamp(20px,3.4vh,34px);border-top:1px solid var(--line);
}
.meta h2{
  position:relative;margin:0 0 9px;padding-top:9px;
  font-size:10px;font-weight:400;letter-spacing:.18em;text-transform:uppercase;color:var(--mute);
}
.meta h2::before{content:'';position:absolute;top:0;left:0;width:14px;height:1px;background:var(--accent)}
.meta p{margin:0;font-size:13px;color:var(--ink);line-height:1.85}
.meta a{border-bottom:1px solid var(--line-2);transition:border-color var(--snap),color var(--snap)}
.meta a:hover{border-color:var(--accent);color:var(--accent-ink)}

.about .cta{margin-top:clamp(24px,4.4vh,42px)}

/* ── PROJECT SHEET — the only vertical scroll on the site ─ */

.sheet{position:fixed;inset:0;z-index:40;background:var(--bg);opacity:0;transition:opacity .2s linear}
.sheet.is-on{opacity:1}
.sheet[hidden]{display:none}

.sheet-scroll{height:100%;overflow-y:auto;overscroll-behavior:contain}

.sheet-x{
  position:fixed;top:clamp(11px,2vh,20px);right:var(--edge);z-index:2;
  width:38px;height:38px;display:flex;align-items:center;justify-content:center;
  background:var(--bg);border:1px solid var(--line-2);font-size:19px;line-height:1;
  transition:background-color var(--snap),border-color var(--snap),color var(--snap);
}
.sheet-x:hover{background:var(--surface);border-color:var(--accent);color:var(--accent-ink)}

.sheet-in{max-width:1180px;margin:0 auto;padding:clamp(22px,5vh,62px) var(--edge) clamp(34px,7vh,84px)}

.sheet-hd{
  display:grid;grid-template-columns:minmax(0,1.3fr) minmax(0,1fr);gap:var(--gap);
  align-items:end;padding-bottom:clamp(18px,3.4vh,34px);border-bottom:1px solid var(--line);
}
/* Project titles are short, so they hold up at a heavier weight than the
   about heading — but still opened up a little. */
.sheet-hd h1{
  margin:0;font-family:var(--dots);font-weight:500;
  font-size:clamp(25px,4.6vw,54px);line-height:1.1;letter-spacing:.025em;
}
.sheet-kick{
  position:relative;margin:0 0 10px;padding-top:10px;
  font-size:10px;letter-spacing:.18em;text-transform:uppercase;color:var(--mute);
}
.sheet-kick::before{content:'';position:absolute;top:0;left:0;width:22px;height:2px;background:var(--accent)}
/* Sits beside the title, above the first photograph. Two short paragraphs
   at most — this is the copy the project's own URL is indexed on. */
.sheet-intro{max-width:52ch}
.sheet-intro p{margin:0;color:var(--mute)}
.sheet-intro p + p{margin-top:11px}

.facts{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(112px,1fr));gap:var(--gap);
  padding:clamp(16px,3vh,30px) 0;border-bottom:1px solid var(--line);
}
.fact{position:relative;padding-left:11px}
.fact::before{content:'';position:absolute;top:3px;left:0;width:3px;height:3px;background:var(--accent)}
.fact span{display:block;font-size:9px;letter-spacing:.18em;text-transform:uppercase;color:var(--mute);margin-bottom:3px}
.fact b{font-weight:400;font-size:13px}

.room{padding:clamp(28px,6vh,76px) 0;border-bottom:1px solid var(--line)}
.room-hd{display:flex;align-items:baseline;gap:14px;margin-bottom:clamp(13px,2.2vh,24px)}
.room-no{font-family:var(--dots);font-size:13px;color:var(--accent-ink)}
.room-hd h2{margin:0;font-size:clamp(15px,2vw,21px);font-weight:400;letter-spacing:.01em}
.room-note{margin:0 0 clamp(13px,2.2vh,24px);color:var(--mute);font-size:13px;max-width:54ch}

/* One photo per row, at its own aspect ratio. Nothing is cropped —
   a render that gets cut in half is worse than a tall page. */
.shots{display:flex;flex-direction:column;gap:var(--gap)}

.shot{position:relative;width:100%;background:var(--surface);border:1px solid var(--line);overflow:hidden}
.shot img{width:100%;height:auto;display:block}
/* only placeholders need a reserved box */
.shot.ph{aspect-ratio:3/2}

.sheet-ft{padding-top:clamp(26px,5vh,66px);display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--gap)}
.sheet-ft p{margin:0;font-family:var(--dots);font-weight:300;font-size:clamp(16px,2.2vw,24px);max-width:24ch;line-height:1.35;letter-spacing:.04em}

/* ── GENERATED PAGES ──────────────────────────────────────
   Two kinds of static document share this stylesheet with the app.

   #pre is the plain-HTML copy of a project, written into /proyek/<slug>/.
   A visitor never sees it — an inline rule in the shell's head hides it the
   moment scripting is detected — so what follows only ever renders for a
   crawler that ignores JavaScript, or for someone who has turned it off.
   It is styled anyway: an unstyled wall of photographs is a bad answer to
   either of them.

   .doc is a service page: an ordinary scrolling article with its own
   header, no app.js, and the same type and colour as everything else. */

/* Release the no-scroll lock the one-screen interface puts on html and
   body. Only html becomes the scroller: giving body `overflow:auto` too
   turns it into a scroll box whose content exactly fits, so it can never
   scroll — and because the base rules also set `overscroll-behavior:none`,
   a wheel event over it is not allowed to chain outwards to html either.
   The page then scrolls programmatically but sits dead under the mouse. */
html.doc-page{overflow:auto;height:auto;overscroll-behavior:auto}
html.doc-page body{overflow:visible;height:auto;overscroll-behavior:auto}

/* ── plain-HTML project copy ─────────────────────────── */

#pre{max-width:820px;margin:0 auto;padding:26px var(--edge) 64px}
.pre-nav,.pre-kick{font-size:10px;letter-spacing:.16em;text-transform:uppercase;color:var(--mute)}
.pre-nav{margin-bottom:26px}
.pre-kick{position:relative;margin:0 0 10px;padding-top:10px}
.pre-kick::before{content:'';position:absolute;top:0;left:0;width:22px;height:2px;background:var(--accent)}
.pre-art h1{margin:0 0 18px;font-family:var(--dots);font-weight:500;
  font-size:clamp(25px,4.6vw,46px);line-height:1.1;letter-spacing:.025em}
.pre-art > p{margin:0 0 13px;max-width:62ch;color:var(--mute)}
.pre-art h2{margin:44px 0 14px;font-size:15px;font-weight:400;letter-spacing:.02em}
.pre-art img{width:100%;height:auto;margin-bottom:var(--gap);border:1px solid var(--line)}
.pre-foot{margin-top:56px;padding-top:26px;border-top:1px solid var(--line);color:var(--mute)}
.pre-foot h2{margin:0 0 10px;font-size:10px;letter-spacing:.18em;text-transform:uppercase}
.pre-foot p{margin:0 0 11px;max-width:62ch}
#pre a{border-bottom:1px solid var(--line-2)}

/* ── service pages ───────────────────────────────────── */

/* ── confirmation page ───────────────────────────────────
   One screen, no navigation, nothing to decide except leaving. Centred
   rather than top-aligned: there is not enough content to justify a
   column, and a short message stranded under a header reads as an error
   rather than as a reply. */

.note{display:flex;min-height:100dvh}
.note-in{
  position:relative;z-index:1;
  margin:auto;max-width:520px;padding:clamp(28px,6vh,64px) var(--edge);
  text-align:center;
}

.note-logo{display:inline-flex;margin-bottom:clamp(26px,5vh,48px)}

/* The rule above the heading is the same 22px accent mark that opens a
   project sheet and the about panel — centred here, because everything
   else on this page is. */
.note-h1{
  position:relative;margin:0 0 16px;padding-top:20px;
  font-family:var(--dots);font-weight:500;
  font-size:clamp(26px,4.6vw,44px);line-height:1.15;letter-spacing:.03em;
}
.note-h1::before{
  content:'';position:absolute;top:0;left:50%;transform:translateX(-50%);
  width:22px;height:2px;background:var(--accent);
}

.note-p{margin:0 auto 12px;max-width:44ch;color:var(--mute);line-height:1.75}

.note-act{
  margin-top:clamp(24px,4.4vh,40px);
  display:flex;flex-direction:column;align-items:center;gap:16px;
}
.note-alt{
  font-size:11px;letter-spacing:.06em;color:var(--mute);
  border-bottom:1px solid var(--line-2);
  transition:border-color var(--snap),color var(--snap);
}
.note-alt:hover{border-color:var(--accent);color:var(--accent-ink)}

.doc-bar{
  position:sticky;top:0;z-index:5;background:var(--bg);
  padding:12px var(--edge);border-bottom:1px solid var(--line);
  display:flex;align-items:center;justify-content:space-between;gap:var(--gap);flex-wrap:wrap;
}
.doc-nav{display:flex;align-items:center;gap:clamp(12px,2vw,26px);flex-wrap:wrap}
.doc-nav a{font-size:11px;letter-spacing:.06em;color:var(--mute);padding:4px 0;border-bottom:2px solid transparent;transition:color var(--snap),border-color var(--snap)}
.doc-nav a:hover{color:var(--ink);border-color:var(--accent)}

/* The dot field is a positioned canvas, so anything meant to sit in front
   of it has to be positioned too — otherwise the grid paints over the
   words. Same reason the app's bar and strip carry a z-index. */
.doc-main{position:relative;z-index:1;max-width:880px;margin:0 auto;padding:clamp(26px,5vh,58px) var(--edge) 0}

.doc-crumb{margin-bottom:clamp(20px,4vh,38px);font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--mute)}
.doc-crumb a{border-bottom:1px solid var(--line-2)}
.doc-crumb a:hover{border-color:var(--accent);color:var(--accent-ink)}

.doc-kick{
  position:relative;margin:0 0 12px;padding-top:12px;
  font-size:10px;letter-spacing:.18em;text-transform:uppercase;color:var(--mute);
}
.doc-kick::before{content:'';position:absolute;top:0;left:0;width:22px;height:2px;background:var(--accent)}

.doc-h1{
  margin:0 0 clamp(16px,2.6vh,24px);font-family:var(--dots);font-weight:500;
  font-size:clamp(26px,4.6vw,50px);line-height:1.12;letter-spacing:.025em;
}
.doc-lead{margin:0 0 13px;max-width:58ch;color:var(--ink);font-size:clamp(14px,1.35vw,17px);line-height:1.75}

.doc-sec{margin-top:clamp(30px,5.4vh,58px);padding-top:clamp(20px,3.2vh,32px);border-top:1px solid var(--line)}
/* Section titles are short, so they can carry the dot-matrix face at a
   size that still reads as a heading rather than as display type. */
.doc-sec > h2{margin:0 0 16px;font-family:var(--dots);font-weight:400;
  font-size:clamp(17px,2.2vw,25px);line-height:1.3;letter-spacing:.04em}
.doc-sec > p{margin:0 0 13px;max-width:64ch;color:var(--mute)}

.doc-list,.doc-steps{
  list-style:none;margin:18px 0 0;padding:0;
  display:grid;grid-template-columns:repeat(auto-fit,minmax(248px,1fr));
  gap:clamp(16px,2.4vw,28px) clamp(18px,3vw,44px);
  counter-reset:step;
}
.doc-list li{position:relative;padding-left:15px}
.doc-list li::before{content:'';position:absolute;top:6px;left:0;width:5px;height:5px;background:var(--accent)}

/* The steps are ordered, so they are numbered — in the dot-matrix face and
   the readable orange, the same pairing the project sheet uses for rooms. */
.doc-steps li{position:relative;padding-left:30px;counter-increment:step}
.doc-steps li::before{
  content:counter(step,decimal-leading-zero);position:absolute;top:-1px;left:0;
  font-family:var(--dots);font-size:13px;color:var(--accent-ink);
}
.doc-list h3,.doc-steps h3{margin:0 0 5px;font-size:12.5px;font-weight:400;letter-spacing:.03em;line-height:1.4}
.doc-list p,.doc-steps p{margin:0;max-width:44ch;font-size:12.5px;line-height:1.7;color:var(--mute)}

.doc-cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(clamp(132px,15vw,178px),1fr));gap:clamp(12px,1.6vw,22px)}
.doc-card{display:block}
.doc-card-fr{
  position:relative;display:block;width:100%;aspect-ratio:3/4;
  background:var(--surface);overflow:hidden;border-radius:6px;
  box-shadow:0 0 0 1px var(--line);transition:box-shadow var(--snap),transform var(--snap);
}
.doc-card-fr img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transition:transform .5s cubic-bezier(.2,.9,.3,1)}
.doc-card:hover .doc-card-fr{box-shadow:0 0 0 1px var(--accent);transform:translateY(-3px)}
.doc-card:hover .doc-card-fr img{transform:scale(1.05)}
.doc-card-nm{display:block;margin-top:9px;font-size:12px;line-height:1.35;transition:color var(--snap)}
.doc-card:hover .doc-card-nm{color:var(--accent-ink)}
.doc-card-sub{display:block;margin-top:2px;font-size:9px;letter-spacing:.12em;text-transform:uppercase;color:var(--mute)}
.doc-more{margin:20px 0 0;font-size:12px}
.doc-more a{border-bottom:1px solid var(--line-2)}
.doc-more a:hover{border-color:var(--accent);color:var(--accent-ink)}

.doc-faq{display:grid;gap:clamp(16px,2.6vh,24px)}
.doc-faq-it{position:relative;padding-left:15px}
.doc-faq-it::before{content:'';position:absolute;top:6px;left:0;width:5px;height:5px;background:var(--accent)}
.doc-faq-it h3{margin:0 0 6px;font-size:13px;font-weight:400;letter-spacing:.02em;line-height:1.45}
.doc-faq-it p{margin:0;max-width:64ch;font-size:12.5px;line-height:1.75;color:var(--mute)}

.doc-cta{
  margin-top:clamp(30px,5.4vh,58px);padding-top:clamp(20px,3.2vh,32px);border-top:1px solid var(--line);
  display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--gap);
}
.doc-cta p{margin:0;font-family:var(--dots);font-weight:300;font-size:clamp(16px,2.2vw,24px);
  max-width:24ch;line-height:1.35;letter-spacing:.04em}

.doc-foot{
  position:relative;z-index:1;
  max-width:880px;margin:clamp(40px,7vh,84px) auto 0;padding:clamp(22px,3.6vh,34px) var(--edge) clamp(34px,6vh,64px);
  border-top:1px solid var(--line);
  display:grid;grid-template-columns:repeat(auto-fit,minmax(168px,1fr));gap:var(--gap);
}
.doc-foot h2{
  position:relative;margin:0 0 9px;padding-top:9px;
  font-size:10px;font-weight:400;letter-spacing:.18em;text-transform:uppercase;color:var(--mute);
}
.doc-foot h2::before{content:'';position:absolute;top:0;left:0;width:14px;height:1px;background:var(--accent)}
.doc-foot p{margin:0;font-size:12px;line-height:1.85}
.doc-foot a{border-bottom:1px solid var(--line-2);transition:border-color var(--snap),color var(--snap)}
.doc-foot a:hover{border-color:var(--accent);color:var(--accent-ink)}

/* ── RESPONSIVE ───────────────────────────────────────── */

@media (max-width:900px){
  .sheet-hd{grid-template-columns:1fr;align-items:start}
  .sheet-intro{margin-top:15px}
}

@media (max-width:760px){
  .card-fr::before,.card-fr::after{display:none}
  /* A square highlight fits a phone better than a 4:3 one. The card is
     held to 62vw so the next one pokes ~34px into the screen — that edge
     is the only cue a first-time visitor gets that the rail can be
     swiped, so it has to be plainly visible rather than a hairline. */
  :root{--wide:1;--card-h:clamp(190px,min(50vh,62vw),380px)}
  .bar{height:auto;padding:10px var(--edge);grid-template-columns:1fr auto;
       grid-template-areas:'logo end' 'tabs tabs';row-gap:9px}
  .logo{grid-area:logo}
  .bar-end{grid-area:end}
  .tabs{grid-area:tabs;justify-self:center}


  .strip{flex-direction:column;align-items:stretch;gap:14px}
  .readout{display:grid;grid-template-columns:repeat(2,1fr);gap:10px 18px}
  .cta-lg{justify-content:center}

}

@media (max-width:400px){
  :root{--logo-h:21px}     /* mark and wordmark shrink together */
  .tabs{gap:13px}
  .cta{padding:7px 12px;font-size:10px}
}

@media (prefers-reduced-motion:reduce){
  *{animation-duration:.001ms!important;transition-duration:.001ms!important}
}
