/* ─────────────────────────────────────────────
   KABASHI PROJEKT — "the drawing sheet"
   Paper and ink, so the studio's own work supplies all the colour. The single
   accent is their red, sampled from their logo, and used only where a drawing
   would use one.
   ───────────────────────────────────────────── */

:root {
  --paper: #f2f0ea;
  --paper-2: #e9e6de;
  --ink: #16181b;
  --ink-2: #4a4d52;
  --ink-3: #8b8d90;
  --rule: #cfcabd;
  --mark: #db382f;              /* the studio's own red, sampled from their logo */
  --font-display: "Instrument Serif", Georgia, serif;
  --font-body: "IBM Plex Sans", system-ui, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, monospace;
  --gap: clamp(1.25rem, 5vw, 4rem);
  --head-h: 60px;
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; }

body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16px; line-height: 1.55;
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }
ol, ul, dl { list-style: none; }
::selection { background: var(--mark); color: var(--paper); }

/* The sheet itself: a drafting grid, faint enough to feel like paper tooth. */
.sheet-grid {
  position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background-image:
    linear-gradient(to right, rgba(22, 24, 27, 0.045) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(22, 24, 27, 0.045) 1px, transparent 1px);
  background-size: 56px 56px;
  mask-image: radial-gradient(ellipse 120% 90% at 50% 0%, #000 40%, transparent 100%);
}

/* ── title block ───────────────────────────── */
.titleblock {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  height: var(--head-h); padding: 0 var(--gap);
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--rule);
}
.titleblock__mark {
  display: flex; align-items: center; gap: 0.55rem;
  font-family: var(--font-mono); font-size: 0.82rem; font-weight: 500;
  letter-spacing: 0.08em; text-transform: uppercase; white-space: nowrap;
}
.titleblock__glyph { color: var(--mark); font-size: 1rem; line-height: 1; }
.titleblock__nav { display: flex; gap: clamp(1rem, 3vw, 2.2rem); }
.titleblock__nav a {
  font-family: var(--font-mono); font-size: 0.78rem; color: var(--ink-2);
  letter-spacing: 0.02em; padding-bottom: 2px;
  border-bottom: 1px solid transparent; transition: color 0.2s, border-color 0.2s;
  white-space: nowrap;
}
.titleblock__nav a:hover { color: var(--ink); border-bottom-color: var(--mark); }
.titleblock__meta {
  font-family: var(--font-mono); font-size: 0.74rem; color: var(--ink-3);
  letter-spacing: 0.06em;
}
@media (max-width: 720px) { .titleblock__meta { display: none; } }
@media (max-width: 480px) {
  .titleblock { gap: 0.5rem; padding-inline: 1rem; }
  .titleblock__mark span:last-child { display: none; }
  .titleblock__nav { gap: 1rem; }
}

/* ── shared ────────────────────────────────── */
.tag {
  font-family: var(--font-mono); font-size: 0.76rem; color: var(--ink-3);
  text-transform: uppercase; letter-spacing: 0.16em;
}
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--font-mono); font-size: 0.8rem; letter-spacing: 0.06em;
  padding: 0.78rem 1.4rem; border: 1px solid var(--ink); border-radius: 0;
  background: var(--ink); color: var(--paper); cursor: pointer; appearance: none;
  transition: background 0.2s, color 0.2s;
}
.btn:hover { background: transparent; color: var(--ink); }
.btn--quiet { background: transparent; color: var(--ink); border-color: var(--rule); }
.btn--quiet:hover { background: transparent; border-color: var(--ink); }
.btn:focus-visible { outline: 2px solid var(--mark); outline-offset: 2px; }

/* Section heads are a rule with the name sitting in it, like a drawing sheet. */
.rule {
  display: flex; align-items: center; gap: 1rem;
  font-family: var(--font-mono); font-weight: 400; font-size: 0.78rem;
  text-transform: uppercase; letter-spacing: 0.18em; color: var(--ink-2);
  margin-bottom: clamp(1.6rem, 4vw, 2.6rem);
}
.rule::after {
  content: ''; flex: 1; height: 1px; background: var(--rule);
}
.block { max-width: 1180px; margin: 0 auto; padding: clamp(3.5rem, 9vw, 7rem) var(--gap) 0; scroll-margin-top: var(--head-h); }
.note { font-family: var(--font-mono); font-size: 0.76rem; color: var(--ink-3); margin-top: 1.4rem; }
.note a { color: var(--ink-2); border-bottom: 1px solid var(--rule); transition: border-color 0.2s, color 0.2s; }
.note a:hover { color: var(--ink); border-bottom-color: var(--mark); }

/* ── cover ─────────────────────────────────── */
/* Full-bleed, and it starts *under* the header rather than below it, so the
   header floats over the image until you scroll past. */
.cover {
  position: relative;
  margin-top: calc(-1 * var(--head-h));
  /* svh first as the floor for browsers without dvh; dvh then tracks the
     viewport as the phone's toolbars slide away, so the cover reaches the
     bottom of the screen in every state instead of leaving a paper strip. */
  min-height: 100svh;
  min-height: 100dvh;
  display: flex; align-items: flex-end;
  overflow: hidden;
  background: #0d0f12;
}
.cover__img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover;
  /* The roof blade and the lit facade are the point — bias off-centre so a
     wide viewport doesn't crop them away. */
  object-position: 50% 38%;
}
/* Two gradients over a flat tint: the top band keeps the header legible, the
   bottom one carries the title and lede, and the tint stops the mid-tones of
   the render from washing out the text between them. */
.cover__scrim {
  position: absolute; inset: 0;
  background-color: rgba(8, 10, 13, 0.16);
  background-image:
    linear-gradient(to bottom, rgba(8,10,13,0.62) 0%, rgba(8,10,13,0.06) 30%),
    linear-gradient(to top, rgba(8,10,13,0.92) 0%, rgba(8,10,13,0.66) 26%, rgba(8,10,13,0.24) 56%, rgba(8,10,13,0.04) 100%);
}
.cover__inner {
  --pad-b: clamp(3.5rem, 9vw, 6rem);
  position: relative; width: 100%; max-width: 1180px; margin: 0 auto;
  padding: 0 var(--gap) var(--pad-b);
  color: #f6f4f0;
}
.cover__tag {
  font-family: var(--font-mono); font-size: 0.76rem;
  text-transform: uppercase; letter-spacing: 0.16em;
  color: rgba(246,244,240,0.72);
}
.cover__name {
  font-family: var(--font-display); font-weight: 400;
  font-size: clamp(3.2rem, 10vw, 7.4rem); line-height: 0.88;
  letter-spacing: -0.015em; margin: 0.5rem 0 0;
  text-shadow: 0 2px 40px rgba(0,0,0,0.45);
}
.cover__name em { font-style: italic; color: rgba(246,244,240,0.75); }
.cover__lede {
  margin-top: 1.4rem; max-width: 38ch;
  font-size: clamp(1rem, 1.5vw, 1.1rem); color: rgba(246,244,240,0.86);
}
.cover__actions { display: flex; gap: 0.7rem; margin-top: 2rem; flex-wrap: wrap; }

.btn--onDark { background: var(--paper); color: var(--ink); border-color: var(--paper); }
.btn--onDark:hover { background: var(--mark); border-color: var(--mark); color: #fff; }
.btn--ghostDark { background: transparent; color: #f6f4f0; border-color: rgba(246,244,240,0.4); }
.btn--ghostDark:hover { background: transparent; border-color: #f6f4f0; color: #f6f4f0; }

/* A caret, not a redline: the old vertical rule was centred on the cover and
   ran straight through the buttons on a phone, and read as a stray mark rather
   than as "there is more below". Anchored to the right edge of the content
   column and bottom-aligned with the actions row, it stays clear of them at
   every width. */
.cover__scroll {
  position: absolute; right: var(--gap); bottom: var(--pad-b);
  display: grid; place-items: center;
  width: 44px; height: 44px;                       /* a real tap target */
  color: rgba(246, 244, 240, 0.55);
  transition: color 0.25s;
}
.cover__scroll:hover, .cover__scroll:focus-visible { color: #f6f4f0; }
.cover__scroll:focus-visible { outline: 2px solid var(--mark); outline-offset: 2px; }
.cover__scroll svg { width: 26px; height: 26px; animation: nudge 2.6s ease-in-out infinite; }
@keyframes nudge {
  0%, 62%, 100% { transform: translateY(0); opacity: 0.75; }
  30% { transform: translateY(6px); opacity: 1; }
}

/* Header floats over the cover, then settles back onto paper. */
.titleblock { transition: background 0.3s, border-color 0.3s, color 0.3s; }
body.over-cover .titleblock {
  background: transparent; backdrop-filter: none;
  border-bottom-color: transparent; color: #f6f4f0;
}
body.over-cover .titleblock__nav a { color: rgba(246,244,240,0.78); }
body.over-cover .titleblock__nav a:hover { color: #fff; border-bottom-color: var(--mark); }
body.over-cover .titleblock__meta { color: rgba(246,244,240,0.6); }

@media (max-width: 860px) {
  .cover__img { object-position: 50% 42%; }
  .cover__lede { max-width: none; }
  /* The text sits over more of the render on a narrow screen, so it needs more
     help than the desktop crop does. */
  .cover__scrim { background-color: rgba(8, 10, 13, 0.26); }
}

/* Below this the two buttons fill most of the line and the gutter beside them
   disappears, so the caret drops into the corner underneath them instead. */
@media (max-width: 620px) {
  .cover__scroll { width: 40px; height: 40px; right: 0.2rem; bottom: 0.35rem; }
  .cover__scroll svg { width: 22px; height: 22px; }
  /* Three actions now (phone, Instagram, Facebook). Letting them wrap on their
     own strands Facebook on a line of its own at some widths and not others, so
     the split is made explicit: the number gets its own row — it is the one a
     client actually taps — and the two profiles share the next. */
  .cover__actions { gap: 0.5rem; }
  .cover__actions .btn { padding: 0.72rem 0.9rem; font-size: 0.76rem; letter-spacing: 0.05em; }
  .cover__actions .btn--onDark { flex: 1 0 100%; }
  .cover__actions .btn--ghostDark { flex: 1 1 0; min-width: 0; }
}

/* ── shërbimet ─────────────────────────────── */
.services { border-top: 1px solid var(--rule); }
.services__item {
  display: flex; align-items: baseline; gap: clamp(1rem, 4vw, 3rem);
  padding: clamp(0.9rem, 2.4vw, 1.4rem) 0;
  border-bottom: 1px solid var(--rule);
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 4.2vw, 2.6rem); line-height: 1.15;
  transition: color 0.25s, padding-left 0.25s;
}
.services__item:hover { color: var(--mark); padding-left: 0.5rem; }
.services__no {
  font-family: var(--font-mono); font-size: 0.74rem; color: var(--ink-3);
  letter-spacing: 0.1em; flex: 0 0 auto;
}

/* ── the mosaic ────────────────────────────── */
/* Full-bleed and on the cover's own dark ground, so the band that starts at the
   top of the page runs all the way through the work before any paper appears.
   Every project is on screen at once — that was the point of dropping the
   carousel, which showed one and hid nine behind a wait. */
.mosaic {
  position: relative;
  background: #0b0d10;
  padding-bottom: clamp(2px, 0.4vw, 6px);
  scroll-margin-top: var(--head-h);
  /* So the row unit below can be stated as a fraction of the mosaic's own
     width rather than the viewport's — vw would drift by the scrollbar. */
  container-type: inline-size;
}
.mosaic__head {
  display: flex; align-items: center; gap: 1rem;
  padding: clamp(2.4rem, 5vw, 4rem) var(--gap) clamp(1.4rem, 3vw, 2.2rem);
  font-family: var(--font-mono); font-weight: 400; font-size: 0.76rem;
  text-transform: uppercase; letter-spacing: 0.2em;
  color: rgba(246, 244, 240, 0.55);
}
.mosaic__head::before {
  content: ''; width: 26px; height: 1px; background: var(--mark); flex: 0 0 auto;
}
.mosaic__head::after {
  content: ''; flex: 1; height: 1px; background: rgba(246, 244, 240, 0.14);
}

/* Twelve columns, and the row unit is one twelfth of the width — the same as a
   column. That is what makes the spans read as proportions instead of arbitrary
   boxes: a tile's shape becomes simply columns ÷ rows, so 7×4 is 1.75:1, 5×3 is
   16:9, 4×2 is 2:1, and the crop off each render stays gentle.
   It has to scale with the width rather than clamp: a fixed cap turns every
   tile on a wide screen into a letterbox slot with the buildings cropped out of
   the top and bottom, which is what a clamped 112px row did here. */
.mosaic__grid {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  grid-auto-rows: 8.333cqw;
  gap: clamp(2px, 0.4vw, 6px);
  padding-inline: clamp(2px, 0.4vw, 6px);
}
.tile[data-c="4"]  { grid-column: span 4; }
.tile[data-c="5"]  { grid-column: span 5; }
.tile[data-c="6"]  { grid-column: span 6; }
.tile[data-c="7"]  { grid-column: span 7; }
.tile[data-c="12"] { grid-column: span 12; }
.tile[data-r="2"] { grid-row: span 2; }
.tile[data-r="3"] { grid-row: span 3; }
.tile[data-r="4"] { grid-row: span 4; }
.tile[data-r="5"] { grid-row: span 5; }

.tile { position: relative; overflow: hidden; min-width: 0; background: #14171b; }
.tile__frame { display: block; width: 100%; height: 100%; cursor: zoom-in; }
.tile__frame img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  filter: saturate(0.94) brightness(0.94);
  transition: transform 0.9s cubic-bezier(0.2, 0.6, 0.2, 1), filter 0.5s;
}
.tile:hover img { transform: scale(1.04); filter: saturate(1.04) brightness(1); }
.tile__frame:focus-visible { outline: 2px solid var(--mark); outline-offset: -4px; }

/* A drafting corner mark on the frame, the same one the drawing sheet uses. */
.tile::after {
  content: ''; position: absolute; right: 10px; bottom: 10px; width: 20px; height: 20px;
  border-right: 2px solid var(--mark); border-bottom: 2px solid var(--mark);
  opacity: 0; transition: opacity 0.3s; pointer-events: none;
}
.tile:hover::after { opacity: 1; }

/* The caption sits on the image rather than under it — a strip of type under
   every tile would rebuild the contact sheet this replaced. It stays legible
   on its own gradient and does not intercept the click. */
.tile__cap {
  position: absolute; inset: auto 0 0 0; pointer-events: none;
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.15rem 0.7rem;
  padding: clamp(2.4rem, 6vw, 4rem) clamp(0.9rem, 1.6vw, 1.4rem) clamp(0.7rem, 1.4vw, 1.1rem);
  /* Deep enough at the foot to carry small mono type over a sunlit render —
     grass and white render are the worst case, and the number sits right on
     them. */
  background: linear-gradient(to top, rgba(8,10,13,0.9) 0%, rgba(8,10,13,0.55) 38%, rgba(8,10,13,0) 100%);
  color: #f6f4f0;
  text-shadow: 0 1px 12px rgba(0, 0, 0, 0.55);
}
.tile__no {
  font-family: var(--font-mono); font-size: 0.7rem; font-weight: 500;
  letter-spacing: 0.16em; color: var(--mark); flex: 0 0 auto;
}
/* Interiors and details take a word where a project takes its number, and take
   it in ink rather than the red, so the numbered run reads as the projects on
   its own without a separate section to say so. */
.tile__no--word {
  color: rgba(246, 244, 240, 0.5); letter-spacing: 0.14em;
  text-transform: uppercase; font-weight: 400;
}
.tile__title {
  font-family: var(--font-display); font-weight: 400; line-height: 1.05;
  font-size: clamp(1.05rem, 1.7vw, 1.7rem);
  text-shadow: 0 1px 24px rgba(0, 0, 0, 0.5);
}
.tile__meta {
  font-family: var(--font-mono); font-size: 0.66rem; letter-spacing: 0.14em;
  text-transform: uppercase; color: rgba(246, 244, 240, 0.74);
  margin-left: auto;
}
.tile__meta i { font-style: normal; color: var(--mark); margin: 0 0.3rem; }

/* The big tiles carry the title at a size worth the render behind it. */
.tile[data-c="7"] .tile__title,
.tile[data-c="12"] .tile__title { font-size: clamp(1.3rem, 2.6vw, 2.6rem); }

/* The credit line, on the mosaic's own ground rather than on paper below it. */
.mosaic__note {
  padding: clamp(1.2rem, 2.6vw, 1.8rem) var(--gap) clamp(2.2rem, 4vw, 3rem);
  font-family: var(--font-mono); font-size: 0.74rem; letter-spacing: 0.04em;
  color: rgba(246, 244, 240, 0.42);
}
.mosaic__note a {
  color: rgba(246, 244, 240, 0.72);
  border-bottom: 1px solid rgba(246, 244, 240, 0.22);
  transition: color 0.2s, border-color 0.2s;
}
.mosaic__note a:hover { color: #f6f4f0; border-bottom-color: var(--mark); }

@media (max-width: 860px) {
  /* Two columns, and the spans collapse to "wide" or "half" — a twelve-column
     mosaic at phone width is just ten slivers. Same idea for the row unit:
     a half-width tile over two rows is 1.85:1, a full-width one over three is
     2.5:1. */
  .mosaic__grid { grid-template-columns: repeat(2, 1fr); grid-auto-rows: 13.5cqw; }
  .tile[data-c] { grid-column: span 1; }
  .tile[data-r] { grid-row: span 2; }
  /* Only the opening and closing tiles stay full width. Any wide tile in the
     middle of the run strands the half-tile beside it — two columns cannot fit
     a half and a full on one row — and auto-placement leaves a hole there
     rather than reordering, which it must not do while the tiles are numbered. */
  .mosaic__grid > .tile:first-child,
  .tile[data-c="12"] { grid-column: span 2; grid-row: span 3; }
  .tile__meta { margin-left: 0; }
  .tile[data-c="7"] .tile__title, .tile[data-c="12"] .tile__title { font-size: 1.5rem; }
  /* No hover on a phone, so the corner mark would never show — and the zoom
     would only ever fire from a tap that is already opening the viewer. */
  .tile::after { display: none; }
}

/* ── viewer ────────────────────────────────── */
.viewer {
  position: fixed; inset: 0; z-index: 60;
  display: grid; place-items: center;
  background: rgba(10, 11, 13, 0.94);
  padding: clamp(1rem, 4vw, 3rem);
  opacity: 0; transition: opacity 0.25s;
}
.viewer[hidden] { display: none; }
.viewer.is-open { opacity: 1; }
.viewer__stage { max-width: min(1400px, 100%); max-height: 100%; display: flex; flex-direction: column; }
.viewer__stage img {
  max-width: 100%; max-height: calc(100vh - 8rem); object-fit: contain;
  display: block; margin: 0 auto;
}
.viewer__stage figcaption {
  font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.12em;
  text-transform: uppercase; color: rgba(246,244,240,0.62);
  text-align: center; margin-top: 1rem;
}
.viewer__close, .viewer__nav {
  position: absolute; background: transparent; border: 0; cursor: pointer;
  color: rgba(246,244,240,0.7); line-height: 1; padding: 0.5rem 0.9rem;
  transition: color 0.2s;
}
.viewer__close:hover, .viewer__nav:hover { color: #fff; }
.viewer__close:focus-visible, .viewer__nav:focus-visible { outline: 2px solid var(--mark); outline-offset: 2px; }
.viewer__close { top: clamp(0.5rem, 2vw, 1.4rem); right: clamp(0.5rem, 2vw, 1.4rem); font-size: 2rem; }
.viewer__nav { top: 50%; transform: translateY(-50%); font-size: clamp(2.4rem, 6vw, 3.4rem); }
.viewer__nav--prev { left: 0; }
.viewer__nav--next { right: 0; }
/* The scroller here is <html>, not <body>, so locking the body alone would let
   the page keep scrolling behind the viewer. */
html:has(body.viewer-open) { overflow: hidden; }

/* ── kontakt ───────────────────────────────── */
.contact { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(1.5rem, 4vw, 3rem); }
.contact dt {
  font-family: var(--font-mono); font-size: 0.72rem; color: var(--ink-3);
  text-transform: uppercase; letter-spacing: 0.14em; margin-bottom: 0.5rem;
}
.contact dd { font-size: 1.05rem; line-height: 1.5; }
.contact dd a { border-bottom: 1px solid var(--rule); transition: border-color 0.2s; }
.contact dd a:hover { border-bottom-color: var(--mark); }
.contact__sep { color: var(--ink-3); margin: 0 0.5rem; }
@media (max-width: 560px) { .contact { grid-template-columns: 1fr; } }

/* ── foot ──────────────────────────────────── */
.foot {
  max-width: 1180px; margin: clamp(4rem, 10vw, 8rem) auto 0;
  padding: 1.6rem var(--gap) 2.4rem;
  border-top: 1px solid var(--rule);
  display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
  font-family: var(--font-mono); font-size: 0.72rem; color: var(--ink-3);
  letter-spacing: 0.04em;
}
.foot__by { color: #a8a49a; }

/* ── reveal ────────────────────────────────── */
/* Scoped to .js so the hidden state only ever exists when there is something
   around to un-hide it. Without the guard, a failed or blocked script leaves
   the entire projects grid at opacity 0 — a blank page that looks broken. */
.js .reveal { opacity: 0; transform: translateY(14px); transition: opacity 0.6s ease, transform 0.6s ease; }
.js .reveal.is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .js .reveal { opacity: 1; transform: none; }
  .tile:hover img { transform: none; }
}
