/* Standard — components that exist only in the WordPress theme.
   The prototype hardcoded these states; real content needs them as reusable rules.
   Anything shared with the prototype belongs in base.css, not here. */

/* ---- graceful gaps: several CPTs are only partly populated ---- */
.thumb-empty{display:flex;align-items:center;justify-content:center;width:100%;height:100%;min-height:8rem;
  background:var(--paper-2);color:var(--ink-soft);font-size:.7rem;letter-spacing:.16em;text-transform:uppercase;
  text-align:center;padding:1rem;opacity:.55}
.work-shot.thumb-empty{aspect-ratio:4/3}

/* ---- heroes with no featured image ----
   The shade layers are gradients tuned to sit over a photo. With no image they fall on white and the
   gold eyebrow disappears. When the hero has no <img>, swap the scrim for solid navy so the type keeps
   its contrast instead of relying on content that may not exist. */
.job-hero:not(:has(img)) .job-hero-shade,
.art-hero:not(:has(img)) .art-hero-shade,
.case-hero:not(:has(img)) .case-hero-shade,
.phero:not(:has(img))::after{background:var(--navy-deep)}
.job-hero:not(:has(img)),
.art-hero:not(:has(img)),
.case-hero:not(:has(img)){background:var(--navy-deep)}
/* A hero sized for a photograph is a wall of flat colour when there is no photograph. Posts without
   a featured image get a shorter band that still reads as a title block. */
.art-hero:not(:has(img)),
.job-hero:not(:has(img)){min-height:0;padding-block:clamp(3.5rem,9svh,6rem)}

/* ---- closing CTA band ----
   Two columns rather than a flex row that pushed the button to the far edge: the copy keeps a
   readable measure on the left, the ways in sit together on the right, and both sit on the same
   baseline. The band is the last thing on most pages, so it is allowed some height. */
/* 28.09.2026: riba on nuud hele. Kliendi soov oli valge pohi. Pind on --paper-2,
   mitte puhas valge, sest lehe enda taust on --paper (0.995) ja puhas valge kaoks
   sellega kokku - riba ei loeks enam eraldi plokina. */
.cta-band {
  position: relative;
  overflow: hidden;
  background: var(--paper-2);
  border: 1px solid var(--line);
  color: var(--ink);
  padding: clamp(2.6rem, 1.6rem + 4vw, 5rem) clamp(2rem, 1.2rem + 3.2vw, 4.5rem);
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  align-items: end;
  gap: clamp(2rem, 4vw, 4.5rem);
}

/* A soft light off the top-left corner so the band reads as a surface rather than as a filled
   rectangle. No asset, and it degrades to exactly the flat navy it used to be. */
/* Valge hoogus heledal pinnal ei tee midagi. */
.cta-band::before { content: none; }

.cta-band > * { position: relative }

.cta-band-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: .7rem;
  font-family: var(--f);
  font-size: .68rem;
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: clamp(1rem, 2vw, 1.6rem);
}

/* The rule belongs to the eyebrow rather than being a separate element to keep aligned. */
.cta-band-eyebrow::before {
  content: "";
  width: clamp(1.6rem, 3vw, 2.8rem);
  height: 1px;
  background: var(--gold);
}

.cta-band h2 { color: var(--navy); max-width: 16ch }
.cta-band-copy p { color: var(--ink-soft); margin-top: 1rem; max-width: 44ch }

.cta-band-act {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: clamp(1.2rem, 2.5vw, 1.8rem);
}

.cta-band-direct { margin: 0; font-size: .8rem; color: var(--ink-soft) }
.cta-band-lines { display: flex; flex-wrap: wrap; gap: .2rem 1.2rem; margin-top: .45rem }

.cta-band-lines a {
  color: var(--navy);
  border-bottom: 1px solid rgba(33, 41, 56, .3);
  padding-bottom: 1px;
  transition: border-color .3s var(--ease);
}

.cta-band-lines a:hover { border-bottom-color: var(--gold) }

.btn--gold { background: var(--gold); color: var(--navy-deep); border-color: var(--gold) }
.btn--gold:hover { filter: brightness(1.06) }
.btn--gold span { display: inline-block; transition: transform .35s var(--ease) }
.btn--gold:hover span { transform: translateX(4px) }

@media (max-width: 820px) {
  .cta-band { grid-template-columns: 1fr; align-items: start }
}

/* ---- section heads shared by archives ---- */
.work-head{margin-bottom:clamp(1.8rem,1rem + 3vw,3.2rem);max-width:34ch}
.work-head h2{margin-top:.6rem}
.work-intro{max-width:60ch;color:var(--ink-soft);margin-bottom:clamp(1.5rem,3vw,2.5rem)}
.worktab small{margin-inline-start:.4rem;font-size:.62rem;opacity:.55;font-variant-numeric:tabular-nums}

/* ---- product card additions ---- */
.pcard-badge{position:absolute;top:.7rem;left:.7rem;font-size:.6rem;letter-spacing:.14em;text-transform:uppercase;
  background:var(--gold);color:var(--navy-deep);padding:.28rem .5rem;font-weight:700}
.pcard-price{display:flex;align-items:baseline;gap:.4rem;font-family:var(--fs);font-weight:300;
  font-size:1.02rem;letter-spacing:-.01em;color:var(--navy);white-space:nowrap}
.pcard-price small{font-family:var(--f);font-size:.66rem;letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink-soft);font-weight:400}
.pcard-price del{font-size:.8rem;color:var(--ink-soft);opacity:.7}

/* ---- product detail additions ---- */
.pdp-price{display:flex;align-items:baseline;gap:.6rem;margin:1.4rem 0}
.pdp-price .lbl{font-size:.66rem;letter-spacing:.18em;text-transform:uppercase;color:var(--ink-soft)}
.pdp-price strong{font-family:var(--fs);font-weight:300;font-size:clamp(1.4rem,1rem + 1.2vw,2rem);letter-spacing:-.02em}
.pdp-price del{color:var(--ink-soft);font-size:1rem}
.pdp-copy,.pdp-specs,.pdp-video,.pdp-pcon{border-top:1px solid var(--line)}
.pdp-copy h2,.pdp-specs h2,.pdp-video h2,.pdp-pcon h2{margin-bottom:1.2rem}
.pdp-files{list-style:none;margin-top:1.6rem;padding-top:1.2rem;border-top:1px solid var(--line)}
.pdp-files li{padding-block:.4rem}
.pdp-files a{font-size:.9rem;color:var(--ink-soft);border-bottom:1px solid var(--line);transition:color .3s var(--ease),border-color .3s var(--ease)}
.pdp-files a:hover{color:var(--navy);border-color:var(--navy)}
.pdp-pcon-frame{position:relative;aspect-ratio:16/10;border:1px solid var(--line);background:var(--paper-2)}
.pdp-pcon-frame iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
@media(max-width:700px){.pdp-pcon-frame{aspect-ratio:3/4}}

/* ---- footer additions (contacts come from the ACF options page) ---- */
.foot-mail{margin-top:1.1rem}
.foot-mail a{font-family:var(--fs);font-weight:300;font-size:1.05rem;border-bottom:1px solid var(--line);
  transition:color .3s var(--ease),border-color .3s var(--ease)}
.foot-mail a:hover{color:var(--navy);border-color:var(--navy)}
.foot-phones{display:flex;flex-wrap:wrap;gap:1.2rem;margin-top:1rem}
.foot-phones a{display:block;font-size:.86rem}
.foot-phones span{display:block;font-size:.62rem;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-soft);margin-bottom:.2rem}
.foot-phones strong{font-weight:500;color:var(--ink)}
.foot-social{display:flex;gap:1rem}
.foot-social a{color:var(--ink-soft);transition:color .3s var(--ease)}
.foot-social a:hover{color:var(--navy)}

/* ---- default page template ---- */
.page-body{max-width:44rem}
.page-body p{margin-bottom:1.4rem;line-height:1.75}
.page-body h2{font-size:clamp(1.4rem,1rem + 1.4vw,2.1rem);margin:clamp(2.2rem,4vw,3.2rem) 0 1rem}
.page-body h3{font-size:1.2rem;margin:2rem 0 .8rem}
.page-body ul,.page-body ol{margin:0 0 1.4rem 1.2rem}
.page-body li{margin-bottom:.5rem;color:var(--ink-soft)}
.page-body img{margin-block:1.6rem}
.page-body a{color:var(--navy);border-bottom:1px solid var(--line)}
.page-body a:hover{border-color:var(--navy)}

/* ---- careers: fallback when the job CPT is still empty ---- */
.job-fallback{max-width:44rem}
.job-fallback p{margin-bottom:1.2rem;line-height:1.7}
.job-fallback a{color:var(--navy);border-bottom:1px solid var(--line)}
.job-fallback a:hover{border-color:var(--navy)}

/* ---- pagination ---- */
.pager{display:flex;justify-content:center;gap:.4rem;margin-top:clamp(2.5rem,5vw,4rem)}
.pager .page-numbers{display:inline-flex;align-items:center;justify-content:center;min-width:2.4rem;height:2.4rem;
  padding-inline:.6rem;border:1px solid var(--line);font-size:.84rem;color:var(--ink-soft);
  transition:color .3s var(--ease),border-color .3s var(--ease),background .3s var(--ease)}
.pager .page-numbers:hover{color:var(--navy);border-color:var(--navy)}
.pager .page-numbers.current{background:var(--navy);border-color:var(--navy);color:#fff}
.pager .screen-reader-text{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%)}

/* ---- showrooms ---- */
.store-hero{display:grid;grid-template-columns:minmax(18rem,.85fr) minmax(0,1.3fr);gap:clamp(2rem,1rem + 4vw,5rem);
  align-items:center;padding:clamp(2.5rem,2rem + 3vw,5rem) var(--edge)}
@media(max-width:900px){.store-hero{grid-template-columns:1fr}}
.store-hero-copy h1{font-size:var(--fs-xl);margin:.6rem 0 clamp(1.5rem,3vw,2.4rem)}
.store-hero-media{overflow:hidden;background:var(--paper-2)}
.store-hero-media img{width:100%;aspect-ratio:16/11;object-fit:cover}
.store-hero-media .thumb-empty{aspect-ratio:16/11}
.store-facts{display:grid;gap:1.1rem;margin-bottom:clamp(1.5rem,3vw,2.2rem)}
.store-facts dt{font-size:var(--fs-eyebrow);letter-spacing:.16em;text-transform:uppercase;color:var(--ink-soft);margin-bottom:.25rem}
.store-facts dd{font-size:.98rem;line-height:1.5}
.store-facts a{border-bottom:1px solid var(--line);transition:color .3s var(--ease),border-color .3s var(--ease)}
.store-facts a:hover{color:var(--navy);border-color:var(--navy)}

.store-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(22rem,100%),1fr));gap:clamp(1.2rem,1rem + 1.5vw,2.4rem)}
.store-card .fr{overflow:hidden;background:var(--paper-2);aspect-ratio:4/3}
.store-card .fr img{width:100%;height:100%;object-fit:cover;transition:transform 1.1s var(--ease)}
.store-card:hover .fr img{transform:scale(1.04)}
.store-card .cap{display:flex;flex-direction:column;gap:.35rem;padding-top:1rem}
.store-card .cap .t{font-size:var(--fs-md);color:var(--navy)}
.store-card .cap .s{font-size:.88rem;color:var(--ink-soft)}

/* ---- article body: styling the blocks WordPress actually outputs ----
   The prototype hand-wrote its figures and quotes. Real posts come out of the editor as
   .wp-block-image / .alignwide / <figcaption> / <blockquote>, none of which exist in the prototype,
   so without these rules an article reads as an undifferentiated column of text. */

.art-body > *{max-width:38rem}

/* Images break out of the measure — that is what makes a post feel visual rather than typed. */
.art-body figure,
.art-body .wp-block-image{margin:clamp(2.2rem,4vw,3.4rem) 0;max-width:none}
.art-body figure img,
.art-body .wp-block-image img{width:100%;height:auto;display:block}
.art-body figcaption,
.art-body .wp-block-image figcaption{margin-top:.75rem;font-size:.8rem;line-height:1.5;
  color:var(--ink-soft);max-width:38rem}
.art-body .alignwide,
.art-body .wp-block-image.alignwide{width:min(100vw - 2 * var(--edge),58rem)}
.art-body .alignfull,
.art-body .wp-block-image.alignfull{width:min(100vw - 2 * var(--edge),64rem)}
.art-body .alignleft{float:none;max-width:24rem;margin-inline-end:2rem}
.art-body .alignright{float:none;max-width:24rem;margin-inline-start:2rem}
.art-body .wp-block-gallery{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(16rem,100%),1fr));
  gap:clamp(.6rem,1.2vw,1rem);max-width:min(100vw - 2 * var(--edge),58rem)}
.art-body .wp-block-gallery figure{margin:0}

/* Pull quote — the same device as the prototype, applied to whatever the editor emits. */
.art-body blockquote,
.art-body .wp-block-quote{margin:clamp(2.4rem,4vw,3.6rem) 0;padding-inline-start:clamp(1.2rem,3vw,2rem);
  border-inline-start:2px solid var(--gold)}
.art-body blockquote p{font-family:var(--fs);font-weight:300;font-style:italic;
  font-size:clamp(1.25rem,1rem + 1.1vw,1.85rem);line-height:1.4;letter-spacing:-.015em;
  color:var(--navy);margin-bottom:.8rem}
.art-body blockquote cite,
.art-body .wp-block-quote cite{font-style:normal;font-size:var(--fs-eyebrow);letter-spacing:.2em;
  text-transform:uppercase;color:var(--ink-soft)}
.art-body .wp-block-pullquote{border-block:1px solid var(--line);border-inline:0;padding-block:clamp(2rem,4vw,3rem);
  margin:clamp(2.4rem,4vw,3.6rem) 0;text-align:start}

.art-body h2{font-size:var(--fs-lg);margin:clamp(2.6rem,4.5vw,3.8rem) 0 1rem;letter-spacing:-.02em}
.art-body h3{font-size:var(--fs-md);margin:clamp(2rem,3.5vw,2.6rem) 0 .7rem}
.art-body ul,.art-body ol{margin:0 0 1.5rem 1.3rem}
.art-body li{margin-bottom:.55rem;line-height:1.7;color:var(--ink)}
.art-body a:not(.btn){color:var(--navy);border-bottom:1px solid var(--line);
  transition:border-color .3s var(--ease)}
.art-body a:not(.btn):hover{border-color:var(--navy)}
.art-body hr,.art-body .wp-block-separator{border:0;border-top:1px solid var(--line);
  margin-block:clamp(2.4rem,4vw,3.4rem)}
.art-body .wp-block-table table{width:100%;border-collapse:collapse;font-size:.92rem}
.art-body .wp-block-table td,.art-body .wp-block-table th{border-bottom:1px solid var(--line);
  padding:.7rem .6rem;text-align:start}
.art-body figure.wp-block-embed,.art-body .wp-block-video{max-width:min(100vw - 2 * var(--edge),58rem)}
.art-body .wp-block-embed__wrapper{position:relative}

.art-tags{margin-top:clamp(2.4rem,4vw,3.4rem);padding-top:1.4rem;border-top:1px solid var(--line);
  display:flex;flex-wrap:wrap;align-items:baseline;gap:.6rem}
.art-tags span{font-size:var(--fs-eyebrow);letter-spacing:.2em;text-transform:uppercase;
  color:var(--ink-soft);margin-inline-end:.4rem}
.art-tags a{font-size:.8rem;color:var(--ink-soft);border:1px solid var(--line);
  padding:.3rem .7rem;border-radius:999px;transition:color .3s var(--ease),border-color .3s var(--ease)}
.art-tags a:hover{color:var(--navy);border-color:var(--navy)}

/* ---- prev/next: keeps every article reachable and gives the reader somewhere to go ---- */
.art-nav{display:grid;grid-template-columns:1fr 1fr;gap:1px;background:var(--line);
  border:1px solid var(--line);margin-bottom:clamp(2.5rem,5vw,4rem)}
@media(max-width:640px){.art-nav{grid-template-columns:1fr}}
.art-nav-item{background:var(--paper);padding:clamp(1.3rem,1rem + 1.4vw,2.1rem);
  display:flex;flex-direction:column;gap:.5rem;transition:background .4s var(--ease)}
.art-nav-item:hover{background:#fff}
.art-nav-next{text-align:end}
.art-nav-lbl{font-size:var(--fs-eyebrow);letter-spacing:.18em;text-transform:uppercase;color:var(--gold);font-weight:700}
.art-nav-t{font-family:var(--fs);font-weight:300;font-size:var(--fs-md);line-height:1.25;
  letter-spacing:-.02em;color:var(--ink);transition:color .35s var(--ease)}
.art-nav-item:hover .art-nav-t{color:var(--navy)}

.art-pager{justify-content:flex-start;margin-top:2rem}

/* ---- Gravity Forms, dressed as the prototype's plain form ----
   The prototype's contact page is hand-written HTML: `.field > label + input`. WordPress renders the
   same form through Gravity Forms, which emits `.gfield > .gfield_label + .ginput_container input`.
   Gravity Forms' own stylesheet is switched off on this site (Forms → Settings → Output CSS), so
   nothing styles that markup — including the anti-spam honeypot, which showed up on the page asking
   visitors to leave "Phone" unchanged. These rules map GF's markup onto the prototype's look.

   Scoped to .form-grid so a form dropped anywhere else keeps whatever styling it had. */

.form-grid .gform_validation_container,
.form-grid .gform_validation_container * {
  position: absolute !important;
  left: -9999px !important;
  width: 1px !important;
  height: 1px !important;
  overflow: hidden !important;
}

.form-grid .gform_wrapper form { margin: 0 }
.form-grid .gform_fields { display: block; margin: 0; padding: 0; list-style: none }

.form-grid .gfield {
  display: flex;
  flex-direction: column;
  gap: .4rem;
  margin-bottom: 1.1rem;
  list-style: none;
}

.form-grid .gfield_label {
  font-size: .78rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--ink-soft);
}

/* GF appends "(Required)" as a span; the asterisk is enough next to an uppercase label. */
.form-grid .gfield_required { color: var(--ink-soft); font-weight: 400 }
.form-grid .gfield_required_text { display: none }

.form-grid .gfield input[type="text"],
.form-grid .gfield input[type="email"],
.form-grid .gfield input[type="tel"],
.form-grid .gfield textarea {
  width: 100%;
  border: 1px solid var(--line);
  border-radius: 3px;
  padding: .85em 1em;
  font: inherit;
  font-size: 1rem;
  background: var(--white);
  color: var(--ink);
}

/* Gravity Forms' "medium" textarea renders rows="10" — 285px against the prototype's 132px, which
   left the left column towering over the aside. Height is pinned rather than the rows attribute
   changed, so it holds whatever size the editor picks in the form builder. */
.form-grid .gfield textarea { height: 8.25rem; min-height: 8.25rem; resize: vertical }

.form-grid .gfield input:focus,
.form-grid .gfield textarea:focus { outline: none; border-color: var(--navy) }

.form-grid .gfield_description { font-size: .82rem; color: var(--ink-soft) }
.form-grid .gfield_description.validation_message { color: oklch(0.55 0.16 25) }

/* The submit is swapped for a real <button class="btn btn--navy"> in functions.php
   (standard_gform_submit_button), so it inherits the prototype's button styling. Only the wrapper
   spacing is left to set here. */
.form-grid .gform_footer { margin-top: 1.4rem; padding: 0 }

.form-grid .gform_confirmation_message {
  border-left: 2px solid var(--navy);
  padding-left: 1rem;
  color: var(--ink);
}

/* The aside's newsletter form is tighter than the main enquiry form: smaller inputs, less air
   between rows. The prototype puts a single email field inline with its button; the real form has
   two fields, so it stacks — but it should not read as heavily as the enquiry form beside it. */
.form-grid aside .gform_wrapper .gform_fields { display: block }
.form-grid aside .gfield { margin-bottom: .7rem; gap: .3rem }
.form-grid aside .gfield_label { font-size: .7rem }
.form-grid aside .gfield input[type="text"],
.form-grid aside .gfield input[type="email"] { padding: .65em .9em; font-size: .95rem }
.form-grid aside .gform_footer { margin-top: 1rem }
.form-grid aside .gform_button { font-size: .82rem; padding: .75em 1.3em }

/* A reCAPTCHA that cannot load renders as a red error box aimed at the site owner, not the visitor.
   Until the key's domain list includes this host it is only noise — keep it out of the layout flow
   rather than letting it push the newsletter block around. */
.form-grid .gfield--type-captcha { margin-bottom: .6rem }
.form-grid .gfield--type-captcha .gfield_label { font-size: .7rem; opacity: .5 }

/* ---- front page deck: category tiles ----
   Replaces the ranked-product tiles. Two things drove the layout:

   1. Product photography here is cut-out-on-white. The old tile put that white cut-out on a
      #f7f7f7 field, so every card showed a visible white rectangle inside a grey one — the single
      thing that made the strip look unfinished. The image field is white now, and the picture is
      given room to breathe instead of being stretched.
   2. A category is read as a word first and a picture second, so the text leads on the left and
      the image sits square on the right, rather than the picture filling the tile. */

.p-cats .cat-cell { justify-content: space-between }

.p-cats .cat-row {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: clamp(.8rem, 1.4vw, 1.6rem);
  flex: 1 1 auto;
  min-height: 0;
}

.p-cats .cat-txt {
  display: flex;
  flex-direction: column;
  gap: .45rem;
  min-width: 0;
}

.p-cats .cat-name {
  font-size: clamp(1.05rem, .85rem + .7vw, 1.6rem);
  font-weight: 400;
  letter-spacing: -.02em;
  line-height: 1.12;
  color: var(--ink);
}

.p-cats .cat-count {
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .11em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

/* Square, white, and padded — a catalogue tile, not a photo crop. `contain` keeps the whole
   product visible; the white ground matches the cut-out so there is no second rectangle. */
.p-cats .cat-img {
  width: clamp(5.5rem, 9vw, 9.5rem);
  aspect-ratio: 1;
  flex: 0 0 auto;
  /* Measured, not guessed: the product shots in this library are cut-outs on a light grey that
     samples at rgb(236,236,236). A white tile behind them drew a second, brighter rectangle inside
     the first — the exact thing that made the old strip look unfinished. Matching the tile to the
     photography makes the edge disappear. If the catalogue is ever reshot on white, change this
     one value to #fff and the tiles follow. */
  background: #ececec;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: clamp(.5rem, .9vw, .9rem);
  overflow: hidden;
}

.p-cats .cat-img img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  transition: transform .5s var(--ease);
}

.p-cats .cat-cell:hover .cat-img img { transform: scale(1.04) }

/* Narrow screens: the tile becomes a row, so the square shrinks rather than shoving the name out. */
@media (max-width: 1040px) {
  .p-cats .cat-img { width: clamp(4.5rem, 18vw, 7rem) }
}

/* ---- catalogue sidebar: the active category ----
   A category page is the shop with one filter on, so the sidebar has to show which one and let you
   take it off again. The active row reads as selected and its count is replaced by a × that links
   back to the unfiltered catalogue — the filter becomes a toggle rather than a dead end. */

.facc-b li.on > a { color: var(--navy); font-weight: 600 }

.facc-b li.on .clear {
  color: var(--ink-soft);
  font-size: 1rem;
  line-height: 1;
  transition: color .3s var(--ease);
}

.facc-b li.on:hover .clear { color: var(--navy) }

/* ---- catalogue sidebar: category icons ----
   The filter headings are the only place in the shop where a whole category is named, so they carry
   the glyph. Sized off the text rather than fixed, so the row stays balanced at any viewport. */

/* base.css sets `justify-content: space-between`, which would have spread icon, label and the
   +/- marker evenly across the row. The icon belongs beside its label, so the row packs from the
   start and the marker is pushed out on its own. */
.facc-h { display: flex; align-items: center; justify-content: flex-start; gap: .6rem }

.facc-icon {
  width: 1.35em;
  height: 1.35em;
  flex: 0 0 auto;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: .75;
}

.facc.open .facc-h .facc-icon { opacity: 1 }

/* The +/- marker was the last child of a plain block; with flex it needs to be pushed to the end. */
.facc-h .pm { margin-left: auto }

/* ---- represented brands: name chip when no logo exists ----
   Only 5 of 21 brands have a logo file. Until the rest arrive the strip prints names, which reads as
   a deliberate list rather than a broken image grid — and each chip is still a working filter. */

.blogo--text {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: .55rem .7rem;
  border: 1px solid var(--line);
  text-align: center;
}

.blogo--text span {
  font-size: .68rem;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-soft);
  line-height: 1.25;
  transition: color .3s var(--ease);
}

.blogo--text:hover span,
.blogo--text.on span { color: var(--navy) }
.blogo--text.on { border-color: var(--navy) }

/* ---- footer ----
   The legal links were printed as adjacent <a> tags with no whitespace between them, so they ran
   together as "MüügitingimusedGarantii üldtingimusedPrivaatsuspoliitika…". A flex row with a gap
   fixes it at the layout level rather than by injecting separator characters into the markup. */

.foot-legal {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem clamp(1rem, 2vw, 2rem);
  justify-content: flex-end;
}

.foot-legal a { transition: color .3s var(--ease) }
.foot-legal a:hover { color: var(--navy) }

/* Ownership on the left, legal on the right. */
.foot-bottom { justify-content: space-between; align-items: baseline }

.foot-copy { display: flex; flex-wrap: wrap; gap: .35rem clamp(.8rem, 1.6vw, 1.6rem) }
.foot-since { color: var(--ink-soft) }

/* Five columns now that social has its own; the first stays wider for the address block. */
.foot-grid { grid-template-columns: 1.6fr repeat(4, 1fr) }

@media (max-width: 1040px) {
  .foot-grid { grid-template-columns: 1fr 1fr }
  .foot-legal { justify-content: flex-start }
}

/* ---- represented brands: real logo files ----
   The logos migrated from standard.ee are square (mostly 408×408) with generous padding baked in,
   where the old CSS assumed a wide strip. `max-height: 100%` on a grid item whose row is sized by
   its own content resolved to nothing, so each image rendered 95×408 — a tall column inside a 2.6rem
   box, showing only blank margin. Sizing the image explicitly fixes it, and the tile is a little
   taller so a square mark has room to read. */

/* base.css makes the tile `display:grid; place-items:center`. A centred grid item does not stretch,
   so `height: 100%` on the image resolved against its own content rather than the tile — the image
   rendered 90px inside a 54px tile and, with `overflow: visible`, spilled onto the row below. Every
   logo overlapped the next one down.

   Flex with max-* constraints cannot do that: the image is never allowed past the tile's box, and
   `overflow: hidden` is belt and braces. */

.blogo {
  height: 3.4rem;
  padding: .5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.blogo img {
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  opacity: .85;
  transition: opacity .3s var(--ease);
}

.blogo:hover img,
.blogo.on img { opacity: 1 }

/* Text chips sit in the same grid, so they need the same height to line up. */
.blogo--text { height: 3.4rem }

/* ---- catalogue: subcategory chips ----
   Fills the empty half of the header block with the next step: siblings when you are inside a
   category, children when you are on a parent, the top level when you are on the plain catalogue.
   Plain links, rendered server-side — see the comment in archive-product.php for why not AJAX. */

/* `.shop-top` was a plain block, so the right half of the header sat empty. Making it a two-column
   grid and pinning everything except the chips to column 1 fills that space without touching the
   markup order — the heading still comes first in the document, which is what a screen reader and a
   crawler read. */
.shop-top {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  column-gap: clamp(2rem, 4vw, 5rem);
  align-items: start;
}

.shop-top > * { grid-column: 1 }

/* Right edge, and sitting on the baseline of the header block rather than floating at the top —
   so the chips read as the last thing before the grid, not as a second heading competing with the
   title. `align-self: end` drops the whole block to the bottom of the row; `justify-content` and
   `align-content: flex-end` pack the chips right and down inside it. */
.shop-subcats {
  grid-column: 2;
  /* `1 / -1` looks like "span every row", but -1 counts back from the last line of the *explicit*
     grid — and there is no `grid-template-rows` here, so every row is implicit and -1 resolved to
     line 1. The chips ended up pinned to the first row, which is why they sat at the top no matter
     what align-self said. An explicit span reaches across the implicit rows. */
  grid-row: 1 / span 10;
  align-self: end;
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  align-content: flex-end;
  gap: .5rem;
  padding-bottom: .35rem;
}

.shop-subcats-lbl {
  flex: 0 0 100%;
  text-align: right;
  font-size: .7rem;
  font-weight: 600;
  letter-spacing: .11em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: .2rem;
}

.shop-subcats .subcat {
  display: inline-flex;
  align-items: baseline;
  gap: .5rem;
  padding: .5rem .9rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: .82rem;
  color: var(--ink);
  background: #fff;
  transition: border-color .3s var(--ease), color .3s var(--ease);
}

.shop-subcats .subcat:hover { border-color: var(--navy); color: var(--navy) }

.shop-subcats .subcat.on {
  border-color: var(--navy);
  color: var(--navy);
  font-weight: 600;
}

.subcat-n { font-size: .72rem; color: var(--ink-soft) }
.subcat.on .subcat-n { color: var(--navy) }

@media (max-width: 900px) {
  .shop-top { grid-template-columns: minmax(0, 1fr) }
  .shop-subcats {
    grid-column: 1;
    grid-row: auto;
    align-self: auto;
    justify-content: flex-start;
    margin-top: 1.4rem;
  }
  .shop-subcats-lbl { text-align: left }
}

/* ---- product page ---- */

/* The quote button was sitting straight against the description. It is the one action on the page,
   so it needs room to be read as one rather than as the next paragraph. */


/* Downloads as tiles: 3D, 2D, datasheet. These are what a specifier came for, so they carry the
   weight of buttons instead of trailing under the price as a bullet list. */
.pdp-docs {
  display: flex;
  flex-wrap: wrap;
  gap: .7rem;
  margin-top: clamp(1.4rem, 2.5vw, 2.2rem);
}

.pdp-doc {
  /* grow, but never below the label's own width — see the note on .pdp-doc-label */
  flex: 1 1 auto;
  min-width: 6.5rem;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: .3rem;
  min-height: 5.5rem;
  padding: 1rem .8rem;
  border: 1px solid var(--line);
  background: var(--paper-2);
  color: var(--ink);
  text-align: center;
  transition: border-color .3s var(--ease), background .3s var(--ease), color .3s var(--ease);
}

.pdp-doc:hover { border-color: var(--navy); background: #fff; color: var(--navy) }

.pdp-doc-label { font-size: 1.05rem; font-weight: 500; letter-spacing: -.01em; line-height: 1.15 }

.pdp-doc-note {
  font-size: .64rem;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.pdp-doc:hover .pdp-doc-note { color: var(--navy) }

/* Thumbnail rail: only as tall as the photo beside it. The rest stay in the DOM (crawlable, and
   visible when JavaScript is off) but are folded away behind the "+N" tile. */
.pdp-thumbs .pdp-thumb:nth-of-type(n + 6) { display: none }

/* Same footprint as a thumbnail so the rail keeps its rhythm, but no hover and no pointer: it is a
   label, not something to press. */
.pdp-more {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 1;
  border: 1px solid var(--line);
  font-size: 1rem;
  font-weight: 500;
  color: var(--ink-soft);
  background: var(--paper-2);
  user-select: none;
}

/* The main shot opens the lightbox, so say so on every viewport rather than only the narrow one. */
.pdp-main { cursor: zoom-in }

/* Main-gallery controls sit over the existing square without changing its size or the two-column
   product layout. They switch the same thumbnail buttons the lightbox already uses, so there is one
   image state rather than a second carousel competing with it. */
.pdp-gallery-nav {
  position: absolute;
  z-index: 2;
  top: 50%;
  width: 2.85rem;
  height: 2.85rem;
  display: grid;
  place-items: center;
  padding: 0;
  border: 1px solid color-mix(in srgb, var(--navy) 18%, transparent);
  border-radius: 50%;
  background: color-mix(in srgb, #fff 88%, transparent);
  color: var(--navy);
  box-shadow: 0 .35rem 1.2rem rgba(16, 33, 67, .1);
  cursor: pointer;
  transform: translateY(-50%);
  transition: background .25s var(--ease), transform .25s var(--ease);
}

.pdp-gallery-nav:hover { background: #fff; transform: translateY(-50%) scale(1.04) }
.pdp-gallery-nav:focus-visible { outline: 2px solid var(--navy); outline-offset: 3px }
.pdp-gallery-prev { left: 1rem }
.pdp-gallery-next { right: 1rem }

.pdp-gallery-count {
  position: absolute;
  z-index: 2;
  right: 1rem;
  bottom: 1rem;
  padding: .42rem .62rem;
  border-radius: 999px;
  background: color-mix(in srgb, #fff 88%, transparent);
  color: var(--navy);
  font-size: .68rem;
  letter-spacing: .1em;
  line-height: 1;
}

.pdp-main:focus-visible { outline: 2px solid var(--navy); outline-offset: 3px }

.lbox.single .lbox-nav,
.lbox.single .lbox-thumbs { display: none }
.lbox.single .lbox-stage { grid-column: 1 / -1 }

@media (max-width: 900px) {
  .pdp-gallery { min-width: 0 }

  .pdp-thumbs {
    width: 100%;
    max-width: 100%;
    overflow-x: auto;
    overscroll-behavior-inline: contain;
    scroll-snap-type: x proximity;
    scrollbar-width: none;
    padding-bottom: .3rem;
  }

  .pdp-thumbs::-webkit-scrollbar { display: none }
  .pdp-thumbs .pdp-thumb { flex: 0 0 4.5rem; scroll-snap-align: start }
  .pdp-thumbs .pdp-thumb:nth-of-type(n + 6) { display: block }
  .pdp-thumbs .pdp-more { display: none }

  .pdp-gallery-nav { width: 2.75rem; height: 2.75rem }
  .pdp-gallery-prev { left: .75rem }
  .pdp-gallery-next { right: .75rem }
  .pdp-gallery-count { right: .75rem; bottom: .75rem }
}

/* "Paigaldusjuhend" is one long word with nowhere to break. Equal-width tiles forced it to wrap
   mid-word — "Paigaldusj / uhend" — which reads as a typo rather than a label.
 *
 * So the row is a flex row, not an equal-column grid: every tile grows to fill the line but no tile
 * is squeezed under the width of its own label. The set stays visually even because the tiles share
 * a height, a border and a baseline; only the widths differ, and only where the word demands it. */
.pdp-doc-label {
  font-size: clamp(.85rem, .78rem + .25vw, 1.05rem);
  overflow-wrap: normal;
  word-break: keep-all;
  white-space: nowrap;
}

/* ---- product page: badges, enquiry, accordion, finishes ---- */

/* "Uus" and the Estonia flag sit above the brand line, where a shopper looks first and where they
   cost no vertical space of their own. */
.pdp-flags {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .5rem;
  margin-bottom: .9rem;
}

.pdp-flag {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  font-size: .68rem;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.pdp-flag--new {
  padding: .28rem .6rem;
  background: var(--navy);
  color: #fff;
  letter-spacing: .14em;
}

.pdp-flag--ee svg { display: block; flex: none }

/* The quantity box and the enquiry button are one form; base.css styles both, this only keeps the
   number input from being taller than the button on Safari. */
.pdp-form { align-items: stretch }
.pdp-qty { margin: 0 }
.pdp-add { line-height: 1.2 }

.pdp-meta { display: flex; flex-direction: column; gap: .4rem }
.pdp-meta span { color: var(--ink-soft) }

/* Accordion.
 *
 * base.css opens a panel by animating max-height to 60rem. That is fine for the prototype's two-line
 * placeholder text and far too short for a real description plus a dimensioned drawing — the panel
 * opened and then clipped mid-sentence. Raising the ceiling is the whole fix; the transition is
 * shortened to match, because a tall ceiling makes a long transition feel like a stall. */
.pdp-specs .spec.open .spec-b { max-height: 200rem }
.pdp-specs .spec-b { transition: max-height .35s var(--ease) }

/* Full-width accordion bars.
 *
 * base.css caps `.pdp-specs` at 60rem, which left the accordion narrower than the rest of the page
 * and the divider bars stopping short of the content edge. Here the accordion fills the full width
 * of the `.pdp` container instead, so every bar runs the whole content width. The body paragraphs
 * keep their own readable measure (base.css `.spec-b p { max-width: 60ch }`), so only the bars grow,
 * not the line length. */
.pdp-specs { max-width: none }
.pdp-specs .spec-b > :first-child { margin-top: 0 }
.pdp-specs .spec-b p { margin: 0 0 .9rem }
.pdp-specs .spec-b strong { color: var(--navy); font-weight: 600 }

/* Each labelled drawing in the specification panel. */
.spec-row + .spec-row { margin-top: 1.6rem }

.spec-row h3,
.pdp-fgroup h3 {
  font-size: .7rem;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin: 0 0 .7rem;
}

.spec-row img { max-width: 26rem; width: 100%; height: auto; display: block }

/* Finishes, grouped by the part of the product they belong to — the repeater already carries that
   grouping and flattening it threw away the only thing that made a strip of swatches readable. */
.pdp-fgroup + .pdp-fgroup { margin-top: 1.6rem }

.pdp-swatches {
  display: flex;
  flex-wrap: wrap;
  gap: 1.1rem;
  align-items: flex-start;
}

/* base.css draws `.pdp-sw` as the prototype's 2rem round colour dot. Here it is a real material
   photo with a caption under it, so every one of those properties has to be undone explicitly —
   leaving `height: 2rem` in place made a 7rem image overflow a 2rem box and the next group's
   heading printed straight over the top of it. */
.pdp-sw {
  margin: 0;
  padding: 0;
  width: 7rem;
  height: auto;
  border: 0;
  border-radius: 0;
  cursor: default;
  display: flex;
  flex-direction: column;
  gap: .5rem;
}

/* `height: auto` matters: WordPress writes height="150" on the tag, and that presentational hint
   beats `aspect-ratio`, so the swatches came out 112x150 instead of square. */
.pdp-sw img {
  width: 100%;
  height: auto;
  aspect-ratio: 1;
  object-fit: cover;
  display: block;
  margin: 0;
  border: 1px solid var(--line);
}

.pdp-sw figcaption { font-size: .78rem; color: var(--ink-soft); line-height: 1.35 }

/* A finish with no swatch image is named rather than drawn as an empty circle: a blank grey square
   labelled "Valge" implies a colour it is not showing. Uploading a graphic upgrades that one finish
   and leaves the rest alone — the two forms are meant to sit side by side. */
.pdp-finish {
  display: inline-flex;
  align-items: center;
  align-self: center;
  padding: .35rem .7rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: .78rem;
  color: var(--ink-soft);
  background: #fff;
}

/* The pCon modal was removed: the configurator refuses to render in an iframe with
   "this configurator is not licensed". See the note in single-product.php. */

.pdp-video { margin-top: clamp(2.5rem, 5vw, 4.5rem) }
.pdp-video h3 { font-size: clamp(1.3rem, 1rem + 1.4vw, 2rem); font-weight: 300; color: var(--navy); margin-bottom: 1.2rem }
.pdp-video iframe { width: 100%; aspect-ratio: 16 / 9; height: auto; border: 0 }

.screen-reader-text {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}


/* The pCon modal was removed: the configurator refuses to render in an iframe with
   "this configurator is not licensed". See the note in single-product.php. */

/* A finish with no swatch image is named rather than drawn as an empty circle. Reads as a fact
   about the product instead of a colour chip that shows no colour. */
.pdp-finish {
  display: inline-flex;
  align-items: center;
  padding: .35rem .7rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: .78rem;
  color: var(--ink-soft);
  background: #fff;
}

/* ---- product accordion: full width ---- */

/* base.css caps `.pdp-specs` at 60rem, which was right when the panel held two lines of placeholder
   copy. It now holds dimensioned drawings and rows of material swatches, and those want the whole
   measure. Text inside still reads at a sane line length because the paragraphs carry their own
   max-width. */
.pdp-specs { max-width: none }
.pdp-specs .spec-b p { max-width: 68ch }

/* ---- brand directory ---- */

/* No hero above it, so the grid needs its own breathing room at the top where the header used to
   provide it. */
.brand-directory--flush { padding-top: clamp(5rem, 8vw, 8rem) }

/* Four across on a desktop, two on a phone. Eight was tried and pulled: at that density each tile
   is about 150px, and a logo set inside a tile's padding ends up 100px wide — small enough that
   half the wordmarks stop being readable, which defeats the point of a logo wall. */
.brand-grid--dense { grid-template-columns: repeat(4, minmax(0, 1fr)) }

@media (max-width: 1100px) { .brand-grid--dense { grid-template-columns: repeat(3, minmax(0, 1fr)) } }
@media (max-width: 700px)  { .brand-grid--dense { grid-template-columns: repeat(2, minmax(0, 1fr)) } }

.brand-grid--dense .brand-face > span {
  font-size: .62rem;
  line-height: 1.2;
  text-align: start;
  overflow-wrap: anywhere;
}

/* A brand with no logo yet gets its name set large in the tile's centre, so the wall keeps its
   rhythm instead of showing an empty square. The small caption underneath still names it, which is
   why this one is styled as a mark rather than repeated as a sentence. */
.brand-wordmark {
  font-family: var(--fs);
  font-weight: 300;
  font-size: clamp(.85rem, .6rem + .55vw, 1.25rem);
  line-height: 1.1;
  text-align: center;
  color: var(--ink-soft);
  align-self: center;
  overflow-wrap: anywhere;
}

.brand-grid--dense .brand-face > span { padding-inline-end: 2rem }

.brand-copy { padding-bottom: clamp(4rem, 8vw, 8rem) }
.brand-copy p { color: var(--ink-soft); line-height: 1.7; max-width: 68ch }

/* ---- front page header: transparent over the hero, solid on scroll ---- */

/*
 * The prototype's front page has its own header — `<header id="head">` with no `.site-head` class,
 * styled entirely by home.css: transparent, white type, pulled up over the hero by a negative
 * margin, turning solid past 24px of scroll.
 *
 * This theme ships one header.php for every page, so that element arrives carrying `.site-head`,
 * and base.css's `.site-head { background: var(--paper) }` (0,1,0) outranks home.css's bare
 * `header { background: transparent }` (0,0,1). The result was a white bar with a white logo and a
 * white burger on it — invisible against itself — while the nav links stayed navy.
 *
 * The scroll behaviour was never broken: home.js has always toggled `.solid` on `#head` off
 * `div.page`'s scrollTop. Only the paint was wrong.
 *
 * Scoped to `body.home` and specific enough (0,2,0 and up) to beat both base.css and home.css, so
 * it does not depend on stylesheet order — home.css is regenerated by tools/sync-assets.py and any
 * fix written there would be lost on the next sync. Same shape as the `.page:has(.case)` block in
 * base.css, which solves this exact problem for case studies.
 */
body.home .site-head {
  background: transparent;
  border-bottom-color: transparent;
  transition: background .5s var(--ease), color .5s var(--ease), border-color .5s var(--ease), box-shadow .5s var(--ease);
}

body.home .site-head .logo,
body.home .site-head .site-nav a,
body.home .site-head .icon-btn,
body.home .site-head .menu-toggle,
body.home .site-head .lang { color: #fff }

body.home .site-head .site-nav a::after { background: #fff }

/* Past the fold the header sits on paper again and everything goes back to navy. */
body.home .site-head.solid {
  background: var(--paper);
  border-bottom-color: var(--line);
  box-shadow: 0 1px 0 var(--line);
}

body.home .site-head.solid .logo,
body.home .site-head.solid .site-nav a,
body.home .site-head.solid .icon-btn,
body.home .site-head.solid .menu-toggle,
body.home .site-head.solid .lang { color: var(--navy) }

body.home .site-head.solid .site-nav a::after { background: var(--navy) }

/* ---- footer layout ---- */

/*
 * Layout only, taken from the ESE Agency footer the client sent as a reference: the mark above the
 * address block, the link columns packed together, a thin rule, and the wordmark filling the width
 * underneath it all. The palette is untouched — a first pass made the whole thing dark, which was
 * copying the reference rather than borrowing from it.
 *
 * The footer is a column that stands at least 70svh tall with its content pushed to the top and the
 * wordmark to the bottom. `space-between` does the work: the block of columns stays tight, and
 * whatever height is left over becomes the gap above the mark rather than padding somebody has to
 * keep re-tuning. Below 70svh of content it simply grows.
 */
.site-foot {
  min-height: 70svh;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding-top: clamp(2rem, 1.4rem + 1.8vw, 3.2rem);
  padding-bottom: 0;
}

/*
 * The footer runs the full window rather than stopping at the 82rem text column.
 *
 * Everywhere else that cap is right — it keeps prose readable. Here it was costing height: five
 * columns squeezed into 82rem on a 1728px screen wrapped the address block onto more lines than it
 * needed, and the whole slab grew taller than a laptop screen. Going wider trades horizontal space,
 * which this layout has plenty of, for vertical space, which it does not.
 */
.site-foot > .wrap {
  max-width: none;
  /*
   * `width` and `margin-inline` both matter, and neither is obvious.
   *
   * base.css gives `.wrap` `margin-inline: auto`. Inside a flex column an item with auto side
   * margins is not stretched — the auto margins win and the item shrinks to fit its content, then
   * centres. So lifting the 82rem cap alone changed nothing: the block still measured 1263px in a
   * 1728px window. Zeroing the margins and asking for the full width is what actually widens it.
   */
  width: 100%;
  margin-inline: 0;
}

.foot-grid { grid-template-columns: 1.4fr repeat(4, 1fr) }

/* Tighter than the default: the columns read as one block, not five scattered lists. */
.foot-grid { gap: clamp(1.2rem, .8rem + 1.4vw, 2.4rem) }
.foot-mark { display: inline-block; margin-bottom: clamp(1rem, 2vw, 1.7rem) }
.foot-mark .logo { margin-bottom: 0 }
.site-foot h4 { margin-bottom: .7rem }
.site-foot .fcol a, .site-foot .fcol p { padding-block: .2rem }
.foot-mail { margin-top: .9rem }
.foot-phones { margin-top: .8rem }

/* All footer navigation headings carry the same navy emphasis. */
.site-foot .fcol h4 {
  color: var(--navy);
  font-weight: 700;
}

/* Five desktop footer items need five columns; the homepage stylesheet only declared four. */
@media (min-width:1041px) {
  .site-foot .foot-grid {
    grid-template-columns:1.4fr repeat(4,minmax(0,1fr));
  }
}

.foot-bottom {
  margin-top: clamp(1.4rem, 2.5vw, 2.2rem);
  padding-top: 1.1rem;
}

/*
 * The wordmark, whole and centred across the full width.
 *
 * An earlier version ran it 112vw wide so the letterforms were cropped by the viewport, copying the
 * way "Get in Contact" bleeds off the reference footer. That works for a phrase and not for a logo:
 * it chopped the S and the D and left the company name reading "TANDAR". A brand mark that cannot
 * be read is not a brand mark.
 *
 * It is printed outside `.wrap` in footer.php so it can span the window rather than the 82rem text
 * column, which is what makes it a full-width mark instead of a large logo.
 */
.foot-word {
  margin: clamp(1rem, 2vw, 1.8rem) 0 0;
  /* Same inset as the columns above it, so the S starts where "STANDARD" starts. */
  padding-inline: var(--edge);
  line-height: 0;
  overflow: hidden;
}

/*
 * Full width, with a ceiling on how much of the screen it may eat.
 *
 * The mark is 160:23, so at full width its height is 14.4% of the window's *width* — which on a
 * short laptop screen is a large share of the window's *height*, and that is what pushed the footer
 * past one screen.
 *
 * The ceiling is applied to the width, not the height, and that is deliberate: `max-height` also
 * works, but it letterboxes. The <svg> box stays full width while `preserveAspectRatio` shrinks the
 * artwork inside it, so the visible S no longer starts where the box does and the mark stops lining
 * up with the columns above. Capping the width keeps box and artwork identical, so the alignment
 * holds; `26svh * 6.95` is simply that height budget converted back through the 160:23 ratio.
 */
.foot-word svg {
  display: block;
  width: min(100%, 26svh * 6.95);
  height: auto;
  margin-inline: auto;
}

/* The footer becomes a deliberate two-column mobile layout instead of five compressed columns. */
@media (max-width:640px) {
  .site-foot {
    min-height:0;
    justify-content:flex-start;
    padding-top:2.25rem;
  }

  .site-foot .foot-grid {
    grid-template-columns:repeat(2,minmax(0,1fr));
    gap:2.25rem 2rem;
  }

  .site-foot .foot-grid > :first-child {
    grid-column:1 / -1;
  }

  .site-foot .foot-grid .tag {
    max-width:30rem;
  }

  .site-foot .foot-bottom {
    flex-direction:column;
    align-items:flex-start;
    gap:1rem;
    margin-top:2.25rem;
  }

  .site-foot .foot-copy {
    flex-direction:column;
    gap:.35rem;
  }

  .site-foot .foot-legal {
    display:grid;
    grid-template-columns:1fr;
    justify-content:start;
    gap:.55rem;
  }

  .site-foot .foot-word {
    margin-top:1.5rem;
  }
}

/* The three business lines reuse the values block's numbered layout, plus an intro paragraph the
   values section does not have. */
.about-areas-intro {
  grid-column: 1 / -1;
  max-width: 46ch;
  margin: 0 0 clamp(2rem, 4vw, 3.5rem);
  color: var(--d-text-soft);
  font-size: clamp(1rem, .85rem + .5vw, 1.35rem);
  line-height: 1.6;
}

/* ---- sector body ---- */

/*
 * The written case for a sector, between the hero and the work. Two columns on a desktop: the
 * heading and prose read as one column, the capability lists as another, so a long list of bullet
 * points never pushes the argument off the screen.
 */
/*
 * This used to be a two-column grid: heading/copy in column 1, the three text lists filling
 * column 2 (see `.sector-lists` below, now dead CSS — the template stopped rendering it when the
 * lists were replaced by the showcase). Left as a grid with nothing in column 2, the copy was
 * pinned to a 52ch column while the other half of the row sat empty — a long sector's copy (the
 * marine brief is five paragraphs) then had to scroll much further than the page width justified.
 * It is a single full-width block now; the copy itself goes to two CSS columns on wide viewports
 * (below) so a long brief still reads side by side without needing an empty second grid column
 * to do it.
 */
.sector-body { padding-block: clamp(3.5rem, 6vw, 7rem) }

.sector-body-title {
  font-family: var(--fs);
  font-weight: 300;
  font-size: clamp(1.9rem, 1.2rem + 2.2vw, 3.6rem);
  line-height: 1.05;
  letter-spacing: -.03em;
  color: var(--navy);
  margin: 0 0 clamp(1.6rem, 3vw, 2.6rem);
  max-width: 24ch;
}

.sector-body-title em { color: var(--ink-soft); font-style: normal }

.sector-body-copy p { color: var(--ink-soft); line-height: 1.7; margin: 0 0 1rem }
.sector-body-copy p:last-child { margin-bottom: 0 }



/* The lists sit in the right-hand column and stack within it. */
.sector-lists {
  grid-column: 2;
  grid-row: 1 / span 3;
  display: grid;
  gap: clamp(1.6rem, 3vw, 2.6rem);
}

.sector-list h3 {
  font-size: .7rem;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin: 0 0 .8rem;
}

.sector-list ul { list-style: none; margin: 0; padding: 0 }

.sector-list li {
  padding: .45rem 0 .45rem 1.1rem;
  border-top: 1px solid var(--line);
  font-size: .92rem;
  line-height: 1.45;
  position: relative;
}

.sector-list li:last-child { border-bottom: 1px solid var(--line) }

/* A rule rather than a bullet glyph: it reads as a specification sheet, which is what it is. */
.sector-list li::before {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  top: 1.05em;
  width: .45rem;
  height: 1px;
  background: var(--ink-soft);
}

.sector-closing {
  margin: clamp(1.6rem, 3vw, 2.6rem) 0 0;
  padding-top: clamp(1rem, 2vw, 1.8rem);
  border-top: 1px solid var(--line);
  font-family: var(--fs);
  font-weight: 300;
  font-size: clamp(1.1rem, .9rem + .7vw, 1.6rem);
  line-height: 1.4;
  color: var(--navy);
  max-width: 46ch;
}

@media (max-width: 900px) {
  /* `.sector-lists` no longer renders (see the note above `.sector-body`); this selector list is
     dead along with the rest of the `.sector-list*` rules, kept for the same reason. */
  .sector-lists { grid-row: auto }
}

/* The Lab enquiry form sits inside the closing CTA block, which is centred and narrow; the form
   needs the full column and left-aligned labels to stay readable. */
.lab-form { margin-top: clamp(2rem, 4vw, 3rem); text-align: start }
.lab-form .gform_wrapper { max-width: 44rem; margin-inline: auto }

/* ---- Standard Lab: palette and the one light section ---- */

/*
 * Standard’s original brand colour, #B08140 (a warm brass/gold), replaces the red-leaning rust that
 * base.css ships by default. It is applied sitewide via a :root override here rather than editing
 * base.css directly, because base.css is regenerated from the prototype by tools/sync-assets.py;
 * overriding the two custom properties lets every existing rule that reads var(--rust) /
 * var(--rust-soft) — on every page, in both light and dark mode — pick up the brand colour without
 * a single one of them being rewritten.
 *
 * `--rust-soft` is the same hue lifted for legibility: a light tint over the default (paper)
 * background, and a slightly different lift — tuned to the same brass — for legibility on navy in
 * dark mode, where the brass at full strength fails contrast at eyebrow sizes.
 */
:root {
  --rust: #B08140;
  --rust-soft: color-mix(in oklch, #B08140 65%, white);
}
body.theme-dark .lab-hero,
body.theme-dark .lab-definition,
body.theme-dark .lab-concepts,
body.theme-dark .lab-process,
body.theme-dark .lab-publishing,
body.theme-dark .lab-for,
body.theme-dark .lab-cta {
  --rust: #B08140;
  --rust-soft: #CDA368;
}

/*
 * Used sparingly, and only where it earns its place: the one button that matters, the step numbers,
 * the eyebrows. base.css also paints it on three section top-borders, where it reads as decoration
 * rather than emphasis — those go back to the neutral hairline.
 */
body.theme-dark .lab-definition-list,
body.theme-dark .lab-for-grid article { border-top-color: var(--d-line) }

/*
 * The enquiry sits on paper while the rest of the page stays navy.
 *
 * Everything above it is a story being told; this is the one place the visitor is asked to do
 * something. Flipping the ground is the cheapest way to say so — no arrow, no animation, just a
 * change of surface. It also makes a form with eleven fields legible, which navy would not.
 */
body.theme-dark .lab-cta > div {
  background: var(--paper);
  color: var(--ink);
}

body.theme-dark .lab-cta > div::after { color: oklch(0.2 0.05 264 / .045) }
body.theme-dark .lab-cta h2 { color: var(--navy) }
body.theme-dark .lab-cta p { color: var(--ink-soft) }
body.theme-dark .lab-cta .eyebrow { color: #8a6a3b }
body.theme-dark .lab-cta .btn { background: var(--navy); color: #fff }

/* Gravity Forms defaults assume a light ground, which is now what it gets — these only fix the bits
   the theme's dark rules would otherwise still be colouring. */
body.theme-dark .lab-form,
body.theme-dark .lab-form label,
body.theme-dark .lab-form legend { color: var(--ink) }
body.theme-dark .lab-form .gfield_label { color: var(--navy) }
body.theme-dark .lab-form .gfield_description { color: var(--ink-soft) }
body.theme-dark .lab-form input[type="text"],
body.theme-dark .lab-form input[type="email"],
body.theme-dark .lab-form textarea,
body.theme-dark .lab-form select {
  background: #fff;
  color: var(--ink);
  border: 1px solid var(--line);
}
body.theme-dark .lab-form .gform_button {
  background: var(--navy);
  color: #fff;
  border: 0;
}

/* ---- Lab enquiry: two columns, and Gravity Forms undressed ---- */

/*
 * Copy left, form right. Eleven fields stacked under a headline is a wall; beside it, the headline
 * stays visible while you fill the form in and the page stops feeling like an afterthought bolted
 * to the bottom of an article.
 */
/*
 * The explicit row track matters more than it looks. The form spans rows 1–4 of column 2 and is
 * roughly 2,000px tall; with implicit rows the browser shared that height across all four rows, so
 * the eyebrow, headline and paragraph in column 1 were pushed hundreds of pixels apart. Sizing the
 * first three rows to their content and letting row 4 absorb the remainder keeps the intro as one
 * tight block at the top.
 */
body.theme-dark .lab-cta > div {
  display: grid;
  grid-template-columns: minmax(0, .85fr) minmax(0, 1.15fr);
  grid-template-rows: auto auto auto 1fr;
  gap: clamp(2rem, 5vw, 6rem);
  align-items: start;
  row-gap: clamp(.9rem, 1.5vw, 1.4rem);
}

body.theme-dark .lab-cta .eyebrow,
body.theme-dark .lab-cta h2,
body.theme-dark .lab-cta > div > p { grid-column: 1 }

/*
 * The headline used to be `position: sticky; top: 7rem` so it stayed visible while the form scrolled
 * past. That worked only while the intro column had hundreds of pixels of accidental space around
 * it. With the rows sized to their content, sticking the headline displaces it up to 7rem down from
 * its own row and it lands on top of the paragraph beneath.
 *
 * Sticking a single grid item among siblings is the mistake — it detaches one row from a stack that
 * is still laid out as a stack. Making it work properly would mean wrapping all three intro elements
 * in one sticky container, which is markup this block does not need: the intro is now four lines
 * tall and reads fine as a static header.
 */

.lab-form {
  grid-column: 2;
  grid-row: 1 / span 4;
  margin-top: 0;
  max-width: none;
}

.lab-form .gform_wrapper { max-width: none; margin: 0 }

/*
 * Gravity Forms wraps radio and checkbox groups in a <fieldset>, which browsers draw with a groove
 * border and a notched legend. That is a 1997 default and it is what made this form look unbuilt.
 */
.lab-form fieldset {
  border: 0;
  padding: 0;
  margin: 0;
  min-width: 0;
}

.lab-form .gform_fields { display: grid; gap: clamp(1.4rem, 2.5vw, 2.2rem) }
.lab-form .gfield { min-width: 0 }

.lab-form .gfield_label,
.lab-form legend.gfield_label {
  display: block;
  font-size: .7rem;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: .8rem;
  padding: 0;
}

.lab-form .gfield_required { color: var(--ink-soft); font-weight: 400 }
.lab-form .gfield_description { font-size: .8rem; color: var(--ink-soft); margin-top: .5rem }

/*
 * Choices as rows on a hairline rather than loose radio buttons: it reads as a specification being
 * filled in, which is what a design brief is.
 */
.lab-form .gchoice {
  display: flex;
  align-items: center;
  gap: .7rem;
  padding: .55rem 0;
  border-top: 1px solid var(--line);
}

.lab-form .gfield_radio .gchoice:last-child,
.lab-form .gfield_checkbox .gchoice:last-child { border-bottom: 1px solid var(--line) }

.lab-form .gchoice label { font-size: .95rem; color: var(--ink); cursor: pointer; margin: 0 }
.lab-form .gchoice input { accent-color: var(--navy); width: 1rem; height: 1rem; flex: none }

.lab-form input[type="text"],
.lab-form input[type="email"],
.lab-form input[type="tel"],
.lab-form textarea {
  width: 100%;
  padding: .8rem .9rem;
  font-family: var(--f);
  font-size: .95rem;
  border-radius: 2px;
}

.lab-form textarea { min-height: 8rem; resize: vertical }

.lab-form input:focus-visible,
.lab-form textarea:focus-visible { outline: 2px solid var(--navy); outline-offset: 1px }

/* The upload control is the one field people hesitate on; give it a dropzone's affordance. */
.lab-form .gfield--type-fileupload input[type="file"] {
  width: 100%;
  padding: 1rem;
  background: var(--paper-2);
  border: 1px dashed var(--line);
  border-radius: 2px;
  font-size: .88rem;
}

/* Name / company / email / phone sit in pairs rather than four full-width boxes in a row. */
@media (min-width: 620px) {
  .lab-form .gform_fields { grid-template-columns: 1fr 1fr }
  .lab-form .gfield { grid-column: 1 / -1 }
  .lab-form .gfield--type-text:nth-last-of-type(-n+3),
  .lab-form .gfield--type-email { grid-column: span 1 }
}

.lab-form .gform_footer { margin-top: clamp(1.5rem, 3vw, 2.2rem) }

.lab-form .gform_button {
  padding: .9rem 2.4rem;
  border-radius: 2px;
  font-family: var(--f);
  font-weight: 700;
  font-size: .85rem;
  letter-spacing: .08em;
  cursor: pointer;
  transition: filter .3s var(--ease);
}

.lab-form .gform_button:hover { filter: brightness(1.15) }

@media (max-width: 900px) {
  body.theme-dark .lab-cta > div { grid-template-columns: 1fr }
  .lab-form { grid-column: 1; grid-row: auto; margin-top: clamp(2rem, 4vw, 3rem) }
}

/* =====================================================================
 * Standard Lab — brought into the homepage's measurements.
 *
 * The Lab page was built on the sub-page system in base.css, and the homepage is a different
 * document (home.css) with a different set of numbers. Side by side the two read as two sites:
 *
 *                          homepage                     Lab (before)
 *   content column         100rem / 1600px              82rem / 1312px  (.wrap)
 *   display headline       clamp(1.7,  .6 + 4.6vw, 5)   clamp(3.1, 1.2 + 7vw, 7.4)
 *   headline tracking      -0.015em, line-height 1.06   -0.045em, line-height 0.91
 *   section heading        clamp(1.7, 1.1 + 2vw, 2.9)   clamp(2,   1 + 3.2vw, 4)
 *   eyebrow                0.26em / 500                 0.22em / 700
 *   section rhythm         clamp(4, 3 + 4vw, 8.5)       clamp(4, 7vw, 8) — and only on two blocks
 *
 * The Lab page was consistently *bigger and narrower*: 288px less width carrying type up to 2.4rem
 * larger. That combination is what made it feel like a different template rather than a heavier
 * one. Everything below closes the gap by adopting the homepage's numbers, not by inventing new
 * ones — every value here is copied from home.css so the two pages stay locked together.
 *
 * Selectors are the `.lab-*` + `.wrap` pairs, which exist nowhere except this template, so none of
 * this needs a body class and none of it can leak onto another page.
 * ================================================================== */

/* 1. Content column. 82rem → 100rem, matching .intro-sec / .svc-sec / .refs / .blog. */
.lab-hero-inner.wrap,
.lab-definition.wrap,
.lab-process.wrap,
.lab-for.wrap,
.lab-cta.wrap,
.lab-concepts > .wrap,
.lab-publishing > .wrap { max-width: 100rem }

/* 2. Vertical rhythm. The homepage breathes on one number; the Lab page had three and left two
      sections with no padding of their own at all. */
.lab-definition.wrap,
.lab-process.wrap,
.lab-for.wrap { padding-block: clamp(4rem, 3rem + 4vw, 8.5rem) }

.lab-concepts,
.lab-publishing { padding-block: clamp(4rem, 3rem + 4vw, 8.5rem) }

/* The CTA opens flush against the block above it (base.css sets padding-top:0) and only needs the
   closing half of the rhythm. */
.lab-cta.wrap { padding-block: 0 clamp(4rem, 3rem + 4vw, 8.5rem) }

/* 3. Hero.
 *
 * The old headline was capped at 11ch — a number chosen for a shorter line, which broke
 * "Koostöö kujundab interjööri tulevikku." across four lines. The template already emits an
 * explicit <br>, so the cap was doing nothing but damage; the copy block carries the width instead,
 * at the homepage's 60rem.
 */
.lab-hero-copy { max-width: 60rem; padding-bottom: clamp(3.4rem, 2rem + 2.4vw, 5rem) }

.lab-hero h1 {
  font-size: clamp(1.7rem, 0.6rem + 4.6vw, 5rem);
  line-height: 1.06;
  letter-spacing: -0.015em;
  max-width: none;
}

.lab-hero .lead {
  font-size: clamp(1.05rem, 1rem + 0.4vw, 1.3rem);
  max-width: 46ch;
  margin-top: clamp(1.2rem, 2vw, 1.8rem);
}

/* 4. Eyebrows. The homepage's is looser and lighter; base.css's is tighter and bold. One of them
      has to win on a page that sits next to the homepage in the same nav. */
.lab-hero .eyebrow,
.lab-concepts .eyebrow,
.lab-process .eyebrow,
.lab-publishing .eyebrow,
.lab-for .eyebrow,
.lab-cta .eyebrow,
.lab-kicker {
  font-size: clamp(0.74rem, 0.66rem + 0.24vw, 0.92rem);
  letter-spacing: 0.26em;
  font-weight: 500;
}

/* 5. Section headings, all four scales collapsed onto the homepage's .hsec-head h2. The CTA keeps
      a step up because it closes the page, the way .refs-top h2 does on the homepage. */
.lab-section-head h2,
.lab-definition h2,
.lab-for > h2 {
  font-size: clamp(1.7rem, 1.1rem + 2vw, 2.9rem);
  font-weight: 400;
  letter-spacing: -0.015em;
  line-height: 1.06;
}

.lab-for > h2 { max-width: 22ch }
.lab-definition h2 { max-width: 24ch }

.lab-cta h2 {
  font-size: clamp(1.8rem, 1rem + 2.6vw, 3.4rem);
  font-weight: 300;
  letter-spacing: -0.02em;
  line-height: 1.05;
}

/* 6. Card headings. At 1600px the grids are wider, so the titles inside them can carry the
      homepage's card scale rather than staying at the sub-page one. */
.lab-concept h3,
.lab-story h3 { font-size: clamp(1.2rem, 1rem + 0.7vw, 1.6rem); line-height: 1.14 }

/* 7. The wider column would otherwise stretch body copy past a comfortable measure. */
.lab-definition p { max-width: 56ch }
.lab-process-list p { max-width: 52ch }

/* 8. The definition block's label gutter was .65fr of three columns — fine at 1312px, but the same
      ratio at 1600px opens a 325px void beside a four-word label and pushes the heading a third of
      the way across the page. Every other heading on this page, and every one on the homepage,
      starts at the edge. Narrowing the gutter gives the width back to the copy.

      Fenced above 900px on purpose: base.css collapses this grid to `1fr 2fr` at 900 and `1fr` at
      640, and `.lab-definition.wrap` (0,2,0) would outrank both of those (0,1,0) at every width —
      pinning three columns onto a phone. */
@media (min-width: 901px) {
  /* Two columns now, not three: the step list that used to occupy the right-hand column has become
     the flow diagram below, which spans the full row. */
  .lab-definition.wrap { grid-template-columns: .4fr 1.85fr }

  /* Same problem one section down: the step number's column was a fraction, so it grew with the
     container and left "01" alone in 424px of empty space. Capped in rem, it stays a margin note
     instead of becoming a third of the row. */
  .lab-process-list li { grid-template-columns: minmax(3rem, 11rem) 1fr }
}

/* =====================================================================
 * 9. The closing block: white to the edges, not a white card on navy.
 *
 * `.lab-cta` carried `.wrap`, so the section itself was 1600px wide and centred inside the navy
 * page, and the white panel was its child. The result was a white rectangle framed on all four
 * sides by navy — it read as a card that had been dropped onto the page rather than as the page
 * changing colour for its final section.
 *
 * The fix moves the constraint inwards: the section goes full-bleed and carries the white, and the
 * inner div takes over the 1600px measure and the edge padding. Same content, same width, but the
 * colour break now runs the full width of the viewport the way a section break should.
 * ================================================================== */
body.theme-dark .lab-cta.wrap {
  max-width: none;
  padding-inline: 0;
  padding-block: 0;
  background: var(--paper);
}

body.theme-dark .lab-cta > div {
  max-width: 100rem;
  margin-inline: auto;
  padding: clamp(3.5rem, 2.5rem + 3.5vw, 7rem) var(--edge);
}

/* The oversized "LAB" watermark was positioned against the old card. Anchored to a full-bleed
   section it would drift off into the page margin, so it is pinned to the text column instead. */
body.theme-dark .lab-cta > div::after { right: max(var(--edge), calc(50% - 50rem + var(--edge))) }

/* =====================================================================
 * 10. The flow diagram — what goes in, what the Lab does, what comes out.
 *
 * Built from text in a grid rather than as an SVG on purpose: every label here is translated,
 * several are editable in ACF, and Estonian runs roughly 15% longer than English. Text baked into
 * an SVG would clip on the first field an editor made longer than the artwork allowed for.
 *
 * The rail reads left to right on desktop and top to bottom on phones, which is why the connecting
 * line is drawn with a pseudo-element on the <ol> and re-oriented in the media query rather than
 * being a border on each item.
 * ================================================================== */
/*
 * The four expanded stages moved inside `.lab-definition`, which is a two-column grid — so the <ol>
 * was auto-placed into a single column and the step copy came out about 180px wide. Like the flow
 * diagram above it, it is a full-width row of that grid, not a column item.
 */
.lab-definition .lab-process-list {
  grid-column: 1 / -1;
  margin-top: clamp(2.5rem, 4vw, 4.5rem);
}

.lab-flow {
  grid-column: 1 / -1;
  margin-top: clamp(2.5rem, 4vw, 4.5rem);
  display: grid;
  grid-template-columns: minmax(0, .9fr) minmax(0, 1.5fr) minmax(0, .9fr);
  gap: clamp(1.5rem, 3vw, 3.5rem);
  align-items: start;
  border-top: 1px solid var(--d-line);
  padding-top: clamp(1.8rem, 3vw, 2.8rem);
}

.lab-flow-lbl {
  display: block;
  font-size: .68rem;
  letter-spacing: .2em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--rust-soft);
  margin-bottom: 1.1rem;
}

.lab-flow-side { position: relative }
.lab-flow-side ul { list-style: none; display: flex; flex-direction: column; gap: .55rem }

/* Direction. Without these the block reads as three unrelated lists side by side; with them it
   reads as one movement, which is the entire point of drawing it. Sat on the rail's own baseline so
   the arrows, the nodes and the connecting line all line up. */
@media (min-width: 901px) {
  .lab-flow-side::after {
    content: "\2192";
    position: absolute;
    top: 1.72rem;
    color: var(--rust);
    font-size: 1rem;
    line-height: 1;
  }
  .lab-flow-side:not(.lab-flow-side--out)::after { inset-inline-end: calc(clamp(1.5rem, 3vw, 3.5rem) / -2 - .35rem) }
  .lab-flow-side--out::after { inset-inline-start: calc(clamp(1.5rem, 3vw, 3.5rem) / -2 - .35rem) }
}

.lab-flow-side li {
  position: relative;
  padding-inline-start: 1.1rem;
  font-size: .92rem;
  line-height: 1.45;
  color: var(--d-text-soft);
}

/* A brass tick rather than a bullet: these are things you have, not a list of options. */
.lab-flow-side li::before {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  top: .62em;
  width: .45rem;
  height: 1px;
  background: var(--rust-soft);
}

.lab-flow-side--out li { color: var(--d-text) }

/* The middle rail. */
.lab-flow-track {
  list-style: none;
  position: relative;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(.6rem, 1.2vw, 1.2rem);
  padding-top: 2.35rem;
}

.lab-flow-track::before {
  content: "";
  position: absolute;
  inset-inline: 0;
  top: 2.05rem;
  height: 1px;
  background: linear-gradient(90deg, var(--rust) 0%, var(--rust-soft) 100%);
  opacity: .55;
}

.lab-flow-track li { position: relative; padding-top: .9rem }

/* The node on the rail. */
.lab-flow-track li::before {
  content: "";
  position: absolute;
  top: -.72rem;
  inset-inline-start: 0;
  width: .5rem;
  height: .5rem;
  border-radius: 50%;
  background: var(--rust);
  box-shadow: 0 0 0 4px var(--d-bg);
}

.lab-flow-n {
  display: block;
  font-family: var(--fs);
  font-size: .95rem;
  color: var(--rust-soft);
  line-height: 1;
}

.lab-flow-track strong {
  display: block;
  margin-top: .4rem;
  font-size: .95rem;
  font-weight: 400;
  line-height: 1.25;
  color: #fff;
}

@media (max-width: 900px) {
  .lab-flow { grid-template-columns: 1fr; gap: 2rem }

  /* The rail turns vertical: one column of steps with the line running down the left of the nodes
     instead of through them horizontally. */
  .lab-flow-track {
    grid-template-columns: 1fr;
    gap: 1.1rem;
    padding-top: 0;
    padding-inline-start: 1.4rem;
  }
  .lab-flow-track::before {
    inset-inline: 0 auto;
    top: .55rem;
    bottom: .55rem;
    height: auto;
    width: 1px;
    background: linear-gradient(180deg, var(--rust) 0%, var(--rust-soft) 100%);
  }
  .lab-flow-track li { padding-top: 0 }
  .lab-flow-track li::before { top: .4rem; inset-inline-start: -1.4rem }
  .lab-flow-n { display: inline; margin-inline-end: .5rem }
  .lab-flow-track strong { display: inline; margin-top: 0 }
}

/* =====================================================================
 * MEIST — brought down to the homepage's scale, and onto paper.
 *
 * Two complaints, one cause. The about page was authored as a standalone showpiece rather than as a
 * page in this site, so nothing on it shares a number with anything else:
 *
 *                        homepage            Meist (before)
 *   content width        1600px              unbounded — 1728px on this screen
 *   section padding      117px               224px  (clamp(7rem, 13vw, 14rem))
 *   display heading      80px                101px manifest / 160px contact / 352px team
 *   number / stat        48px                144px
 *
 * A 352px word is not emphasis at that point, it is the only thing on the screen — which is exactly
 * what "liiga laiali ja suurelt" describes. Every replacement below is a homepage value, not a new
 * one, so the two pages stay locked together the way the Lab page now does.
 *
 * All of it lives here rather than in base.css because base.css is regenerated from the prototype
 * by tools/sync-assets.py and would lose these on the next sync.
 * ================================================================== */

/* ---- 1. Paper by default. `.about-dark` still wins inside the two navy bands. ---- */
.about-page { background: var(--paper); color: var(--ink) }

/* ---- 2. Measure and rhythm ---- */
.about-section {
  max-width: 100rem;
  margin-inline: auto;
  padding: clamp(4rem, 3rem + 4vw, 8.5rem) var(--edge);
}

/*
 * The manifest reserved a full viewport for one heading and one paragraph. On a laptop that is a
 * screen of mostly nothing before the page has said anything, and it is the single biggest reason
 * the page felt spread out.
 */
.about-manifest { min-height: 0; grid-template-columns: .4fr 2.6fr; gap: clamp(2rem, 4vw, 5rem) }
.about-manifest h2 { font-size: clamp(1.9rem, 1.2rem + 2.6vw, 3.6rem); line-height: 1.1; max-width: 22ch }
.about-manifest-copy { margin-top: clamp(1.6rem, 3vw, 2.6rem); max-width: 52ch }

/* ---- 3. The two navy bands need their own top padding back.
        `.about-facts` had `padding-top: 0` because it used to butt against the manifest inside the
        same dark wrapper. It is a band in its own right now. ---- */
.about-facts { padding-top: clamp(4rem, 3rem + 4vw, 8.5rem) }
.about-facts > div:not(.about-office-list) { padding-bottom: clamp(2rem, 4vw, 3.5rem) }
/* Close to the homepage's own stat size (`.metarow .v`, 48px) rather than to a headline — these are
   figures in a band, not the page's title. */
.about-facts strong { font-size: clamp(2.2rem, 1.5rem + 2vw, 3.6rem) }
.about-office-list { margin-top: clamp(2rem, 4vw, 3rem) }
.about-office-list p { font-size: clamp(1rem, .9rem + .4vw, 1.35rem); padding-block: .85rem }

/* ---- 4. Story ---- */
.about-story-side { margin-top: clamp(3rem, 7vw, 7rem) }
.about-story-copy { padding-top: clamp(1rem, 2.5vw, 2.5rem) }
.about-story-copy h2 { font-size: clamp(1.7rem, 1.1rem + 2vw, 2.9rem); margin-block: clamp(1rem, 2vw, 1.6rem) }

/* ---- 5. Team.
        The 352px wordmark was the loudest thing on the site, larger than anything on the homepage
        by a factor of four. It stays a display element — just one that fits on the screen with the
        rest of the section. ---- */
.about-team { padding-bottom: clamp(4rem, 3rem + 4vw, 8.5rem) }
/*
 * Capped at the homepage hero's size, deliberately: nothing on a sub-page should be larger than the
 * largest thing on the front page. The first pass brought this from 352px to 144px and it still
 * filled the screen on its own, which is the tell that the ceiling has to be a shared number rather
 * than a smaller guess.
 */
.about-team header > h2 {
  font-size: clamp(1.7rem, 0.6rem + 4.6vw, 5rem);
  line-height: .86;
  letter-spacing: -.04em;
  margin-block: clamp(2rem, 4vw, 4rem);
}
.about-team header > p:last-child {
  width: min(38rem, 100%);
  margin: 0 0 clamp(2.5rem, 5vw, 5rem) auto;
  font-size: clamp(1rem, .9rem + .4vw, 1.3rem);
}
.about-people { gap: clamp(2.5rem, 4vw, 4rem) clamp(1rem, 2vw, 2rem) }

/* ---- 6. Values / areas ---- */
.about-values > .about-label { margin-bottom: clamp(1.8rem, 3vw, 3rem) }
.about-value { padding-block: 1.3rem; gap: clamp(1.2rem, 3vw, 2.5rem) }
.about-value h2 { font-size: clamp(1.5rem, 1rem + 1.6vw, 2.6rem) }

/* ---- 7. Sustainability ---- */
.about-sustain h2 { font-size: clamp(1.7rem, 1.1rem + 2vw, 2.9rem); margin-block: clamp(1rem, 2vw, 1.6rem) }
.about-sustain figure { height: min(56vh, 34rem) }

/* ---- 8. Contact ---- */
.about-contact { padding-bottom: clamp(4rem, 3rem + 4vw, 8.5rem) }
.about-contact h2 {
  font-size: clamp(2.2rem, 1rem + 4vw, 4.6rem);
  line-height: .98;
  letter-spacing: -.035em;
  margin-block: clamp(2rem, 4vw, 4rem);
}
.about-contact > div { width: min(45rem, 100%) }
.about-contact a { font-size: clamp(1rem, .9rem + .4vw, 1.35rem); padding-block: .95rem }

/* ---- 9. Hero.
        Down to the homepage's display size. The old 131px was set against a full-bleed photo with
        nothing else on it, which is the one place oversized type is free — but it also set the
        expectation that the rest of the page would be that big, and the rest of the page obliged. ---- */
.about-hero h1 {
  font-size: clamp(1.7rem, 0.6rem + 4.6vw, 5rem);
  line-height: 1.06;
  letter-spacing: -.03em;
  max-width: 20ch;
}

/* =====================================================================
 * 10. The light palette gaps.
 *
 * pages.css already had an `.about-light` block, but it was written when exactly one section used
 * it, so it only covers what the team section contains. Now that five of the seven bands are light,
 * the greys base.css hardcoded for navy — #aaa body copy, #383838 rules, #777 captions — turn up on
 * paper, where they are either unreadable or invisible. These are the ones it missed.
 * ================================================================== */
.about-light .about-manifest h2 em { color: var(--ink-soft) }
.about-light .about-manifest-copy { color: var(--ink-soft) }
.about-light .about-story-copy > span { color: var(--ink-soft) }
.about-light .about-story-copy p { color: var(--ink-soft) }
.about-light .about-facts > div:not(.about-office-list),
.about-light .about-office-list,
.about-light .about-office-list p { border-color: var(--line) }
.about-light .about-facts span { color: var(--ink-soft) }
.about-light .about-office-list p i { color: var(--ink-soft) }
.about-light .about-areas-intro { color: var(--ink-soft) }
.about-light .about-person figure { background: var(--paper-2) }

/*
 * base.css greys only the *last* paragraph of the sustainability block (`.about-sustain > div > p:
 * last-child`). Against navy the difference between #f4f3ef and #999 barely registered; on paper
 * one paragraph in ink beside one in grey reads as a mistake. Both take the body colour.
 */
.about-light .about-sustain > div > p { color: var(--ink-soft) }

@media (max-width: 900px) {
  /* base.css collapses the manifest to one column here; my desktop rule has equal specificity and
     loads later, so it has to be restated rather than left to base. */
  .about-manifest { grid-template-columns: 1fr }

  /* Likewise: base.css zeroes the story's offset image on mobile, where a 3rem drop just opens a
     gap between two stacked photos. */
  .about-story-side { margin-top: 0 }
}

/* =====================================================================
 * The WordPress admin bar vs. a fixed page container.
 *
 * `.page` is `position: fixed; inset: 0` — it owns the whole viewport and does its own scrolling.
 * WordPress then paints its 32px admin bar over the top of it, so for any logged-in editor the top
 * 32px of the site header is covered: the language switcher's button sits at y=25 and is literally
 * unclickable, which is exactly what it looks like when a feature "doesn't work".
 *
 * `.page` has an `inset` transition for the menu slide, so the offset goes on `top` only —
 * overriding `inset` wholesale here would fight that animation.
 * ================================================================== */
body.admin-bar .page { top: 32px }

/* WordPress switches the admin bar to 46px and makes it non-fixed below 783px. */
@media screen and (max-width: 782px) {
  body.admin-bar .page { top: 46px }
}

/* =====================================================================
 * Standard Lab × Plaat Detail — the SIPA case, promoted out of the card grid.
 *
 * Three paragraphs of argument do not fit in a tile. This is the page's evidence — named partner,
 * named material, measurable result — so it gets the width to make the case: copy on the left at a
 * readable measure, the photograph holding the right half.
 * ================================================================== */
.lab-case {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 5.5rem);
  align-items: center;
  padding-block: clamp(4rem, 3rem + 4vw, 8.5rem);
}

.lab-case-copy .eyebrow { display: block }

.lab-case h2 {
  font-size: clamp(1.7rem, 1.1rem + 2vw, 2.9rem);
  font-weight: 400;
  letter-spacing: -.015em;
  line-height: 1.06;
  color: #fff;
  margin-top: .7rem;
  max-width: 18ch;
}

.lab-case-body { margin-top: clamp(1.2rem, 2.5vw, 2rem) }
.lab-case-body p { color: var(--d-text-soft); line-height: 1.7; max-width: 52ch }
.lab-case-body p + p { margin-top: 1rem }

.lab-case .arrow-link { color: #fff; margin-top: clamp(1.4rem, 2.5vw, 2rem) }

/*
 * Two photographs now, not one — the finished panel and the panel being tested.
 *
 * They are deliberately unequal. Equal halves would read as a gallery, and a gallery says "here are
 * some pictures"; a large image with a smaller captioned one beneath it says "here is the thing, and
 * here is the evidence". The caption belongs to the test shot alone, which is why it lives on the
 * second figure rather than under the pair.
 */
.lab-case-media { display: grid; gap: clamp(.9rem, 1.6vw, 1.4rem) }
.lab-case-media figure { overflow: hidden; background: var(--d-tile); aspect-ratio: 4 / 3; margin: 0 }
.lab-case-media img { width: 100%; height: 100%; object-fit: cover; display: block }

/* The supporting shot: shallower, so the pair reads as one column rather than as two equal tiles. */
.lab-case-media--sub { aspect-ratio: auto !important; background: none !important }
.lab-case-media--sub img { aspect-ratio: 16 / 9; height: auto }
.lab-case-media--sub figcaption {
  margin-top: .7rem;
  font-size: .78rem;
  line-height: 1.5;
  letter-spacing: .01em;
  color: var(--d-text-soft);
  max-width: 44ch;
}

/*
 * No photo yet — and there is no real SIPA photograph in the library, so this is the state the
 * section actually ships in rather than an edge case.
 *
 * Collapsing to one column left the heading and the copy hugging the left edge with half the row
 * empty, which looks like a broken two-column layout rather than a deliberate one. So without an
 * image the block becomes heading-left / text-right — the same shape as `.lab-definition` above it,
 * which is the page's established way of setting a statement against its explanation.
 */
.lab-case:not(:has(.lab-case-media)) { grid-template-columns: minmax(0, 1fr) }
.lab-case:not(:has(.lab-case-media)) h2 { max-width: 24ch }
.lab-case:not(:has(.lab-case-media)) .lab-case-body p { max-width: 66ch }

/*
 * "Kellele on Standard Lab?" — the answer is one sentence, so it is set as the statement rather
 * than as an introduction to something else. Wider than the other headings on the page because it
 * lists four audiences and should not break into six lines doing it.
 */
.lab-for > h2 { max-width: 30ch }

@media (max-width: 900px) {
  .lab-case { grid-template-columns: 1fr; gap: 2rem }
  .lab-case-media { order: -1; aspect-ratio: 16 / 10 }
}

/* A language with no translation behind it: shown, explained, not clickable. */
.langsw-o.is-missing { cursor: default; opacity: .45 }
.langsw-o.is-missing:hover { background: none; color: var(--ink-soft) }
.langsw-na {
  display: block;
  width: 100%;
  margin-top: .15rem;
  font-size: .62rem;
  letter-spacing: .1em;
  text-transform: uppercase;
}
.langsw-o.is-missing { flex-wrap: wrap }
.langsw-o.is-missing .langsw-na { margin-inline-start: 2.4rem }
body.theme-dark .langsw-o.is-missing:hover { background: none; color: var(--d-text-soft) }

/* The accordion title is an <h2> wrapping the button, purely for the document outline — it must not
   pick up heading sizing or spacing, the button owns all of that. */
.spec-t { margin: 0; font: inherit; letter-spacing: inherit; line-height: inherit }
.spec-t > .spec-h { width: 100% }

/* Lab hero sits too low.
   `.lab-hero-copy` is bottom-anchored (`margin-top:auto`) and then pads itself down by another 12vh
   — 102px on a laptop — so the headline started roughly a third of the way down the image. The block
   keeps its bottom anchor, but the padding above it comes off so the text rises into the frame. */
.lab-hero-copy { padding-top: clamp(1.5rem, 3vh, 3rem) }

/* =====================================================================
 * Mobile scrolling.
 *
 * `.page` is a fixed, self-scrolling container. Without `overscroll-behavior` a swipe past the top
 * or bottom chains to the document behind it: on iOS the whole fixed layer rubber-bands away from
 * the viewport and snaps back, which reads as the page tearing loose. `contain` keeps the gesture
 * inside the container it started in.
 *
 * The overlay menu and the search panel get it too — a scroll inside either used to escape to the
 * page underneath once it hit its own end.
 * ================================================================== */
.page,
.menu-inner,
.search-ov { overscroll-behavior: contain }

/* Momentum scrolling on older iOS, where a fixed overflow container is otherwise sticky and slow. */
.page { -webkit-overflow-scrolling: touch }

/* =====================================================================
 * The mobile scroll glitch, and where it actually came from.
 *
 * The services stepper un-pins below 921px — but its autoplay does not. An IntersectionObserver
 * advances the step every 4.2s, and `.svc-meta` switches from `position:absolute` to
 * `position:relative` when it becomes active. On desktop `.svc-card` has a fixed min-height that
 * absorbs the difference; the mobile rules set `min-height:0`, so each swap resized the card and
 * shoved everything below it up or down — every four seconds, mid-scroll.
 *
 * Rather than freeze the height at a guessed number, the four panels are stacked in one grid cell.
 * The card is then as tall as its tallest panel at all times and switching is pure opacity: no
 * reflow can happen, whatever the copy grows to.
 * ================================================================== */
@media (max-width: 920px) {
  .svc-card {
    display: grid;
    grid-template-areas: "svc";
  }

  .svc-meta,
  .svc-meta.is-active {
    grid-area: svc;
    position: static;
  }

  /* The image frames stack the same way, for the same reason. */
  .svc-img { display: grid; grid-template-areas: "svcimg" }
  .svc-frame,
  .svc-frame.is-active { grid-area: svcimg; position: static }
}

/* =====================================================================
 * Sector pages — offices / hotels / ships.
 *
 * The page was hero → heading → paragraph → three bullet lists → closing line: five text blocks in
 * a column, nothing to look at between the photographs at the top and the reference grid at the
 * bottom. Two changes, both structural rather than decorative.
 * ================================================================== */

/* 1. A measured band between the hero and the prose. Counted from the database — see the template. */
.sector-figures {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: clamp(1.5rem, 3vw, 3rem);
  padding-block: clamp(2.5rem, 4vw, 4.5rem);
  border-bottom: 1px solid var(--line);
}

.sector-figures strong {
  display: block;
  font-family: var(--fs);
  font-weight: 300;
  font-size: clamp(2.2rem, 1.5rem + 2vw, 3.6rem);
  line-height: 1;
  color: var(--navy);
}

.sector-figures span {
  display: block;
  margin-top: .55rem;
  font-size: .8rem;
  line-height: 1.4;
  color: var(--ink-soft);
  max-width: 18ch;
}

/*
 * 2. The three lists become three numbered blocks instead of three anonymous <ul>s.
 *
 * Dead code as of the sector-page redesign: `taxonomy-reference_type.php` no longer renders
 * `.sector-list`/`.sector-lists`/`.sector-list--tags`/`.sector-list--proof` at all (see the
 * comment above `.sector-body` further up this file for why, and `$standard_capabilities` in
 * functions.php for what replaced it). Left in place rather than deleted, same call as the other
 * orphaned block above — a second developer grepping "sector-list" while triaging a future bug
 * should find this note before assuming either block is still live.
 */
.sector-list { position: relative; border-top: 1px solid var(--line); padding-top: 1.1rem }

.sector-list-no {
  display: block;
  font-family: var(--fs);
  font-size: .95rem;
  color: var(--gold);
  line-height: 1;
  margin-bottom: .9rem;
}

.sector-list h3 {
  font-size: clamp(1.05rem, 1rem + .35vw, 1.3rem);
  font-weight: 500;
  color: var(--navy);
  margin-bottom: .8rem;
}

.sector-list ul { list-style: none; display: flex; flex-direction: column; gap: .5rem }

.sector-list li {
  position: relative;
  padding-inline-start: 1.1rem;
  font-size: .92rem;
  line-height: 1.5;
  color: var(--ink-soft);
}

.sector-list li::before {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  top: .66em;
  width: .45rem;
  height: 1px;
  background: var(--gold);
}

/*
 * 2b. Category lists (short one-line capabilities, no "Name — detail" entries) read as a tag
 * cloud instead of a spec-sheet column — see the per-item detection in taxonomy-reference_type.php.
 * Two classes beats the one-class `.sector-list ul`/`.sector-list li` rules above without !important.
 */
.sector-list--tags ul {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  gap: .55rem;
}

.sector-list--tags li {
  display: inline-flex;
  align-items: center;
  padding: .5rem 1rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--paper-2);
  font-size: .85rem;
  line-height: 1.2;
}

.sector-list--tags li::before { content: none }

/* Proof lists ("Selected projects") keep the row layout; the name scans first, the detail is a
   quieter second line instead of running on in the same sentence. */
.sector-list--proof li { padding-block: .6rem }
.sector-list--proof li strong { color: var(--navy); font-weight: 500 }

.sector-list--proof li span {
  display: block;
  margin-top: .2rem;
  font-size: .82rem;
  color: var(--ink-soft);
}

/*
 * 2c. The showcase — capability cards, a small carousel of the sector's own work, and a row of
 * furniture categories — replacing the three text lists above (kept in place as dead CSS rather
 * than deleted; see the note in taxonomy-reference_type.php on why the template no longer renders
 * `.sector-list`). Three unrelated widgets share one section because they are read together, top
 * to bottom, as one answer to "what does Standard do here": the capability band says what, the
 * work band proves it, the solutions row says what it is made of.
 */
.sector-showcase { padding-block: clamp(3.5rem, 5.5vw, 6rem); border-bottom: 1px solid var(--line) }

.sector-showcase-title {
  font-size: clamp(.78rem, .72rem + .2vw, .9rem);
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin-bottom: clamp(1.2rem, 2vw, 1.8rem);
}

/* The capability carousel: a heading row carrying the two round arrow buttons, the track under
   it, and a row of dots below that. The track holds more cards than fit in one view, so the
   buttons and the dots page it for real; `.is-static` is set by site.js when a width does fit
   everything and there is genuinely nothing to page, and hides the chrome rather than leaving
   controls that do nothing.

   The arrows used to flank the track, which pushed the cards ~40px inside the measure every other
   block on the page sits on. Up here they cost the track no width at all. */
.showcase-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  margin-bottom: clamp(1.2rem, 2vw, 1.8rem);
}

.showcase-head .sector-showcase-title { margin-bottom: 0 }
.showcase-nav { display: flex; gap: .5rem; flex: 0 0 auto }
.showcase-carousel { display: block }
.showcase-block.is-static .showcase-nav { display: none }

.showcase-arrow {
  flex: 0 0 auto;
  width: clamp(2.3rem, 1.9rem + .8vw, 2.8rem);
  aspect-ratio: 1;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--paper);
  color: var(--navy);
  cursor: pointer;
  display: grid;
  place-items: center;
  transition: background .35s var(--ease), color .35s var(--ease);
}

.showcase-arrow svg { width: 55%; height: 55%; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round }
.showcase-arrow:hover { background: var(--navy); color: #fff }
.showcase-arrow:disabled { opacity: .35; cursor: default }
.showcase-arrow:disabled:hover { background: var(--paper); color: var(--navy) }

/* The bottom margin used to separate the dots from the block that followed them inside this
   section. Nothing follows them now — the solutions list moved up into the body section — so the
   section's own padding is the only gap needed, and the old margin was stacking on top of it. */
.showcase-dots { display: flex; justify-content: center; gap: .6rem; margin: 1.1rem 0 0 }
.showcase-dots button { width: 8px; height: 8px; border-radius: 50%; border: 1px solid var(--line); background: transparent; padding: 0; cursor: pointer; transition: background .3s var(--ease), transform .3s var(--ease) }
.showcase-dots button.on { background: var(--gold); border-color: var(--gold); transform: scale(1.2) }

/* A track rather than a grid that always fits: three cards per view on a wide screen, snapping,
   with the native scrollbar hidden because the arrows and dots are the visible control. Overflow
   is the point here — it is what gives the carousel something to move. */
/* A track rather than a grid that always fits: three items per view on a wide screen, snapping,
   with the native scrollbar hidden because the arrows and dots are the visible control. Overflow
   is the point here — it is what gives the carousel something to move.

   No gap, because the items are separated by a hairline rather than by space (see below), and a
   gap would push that line off the halfway point between two columns. */
.sector-cap-row {
  flex: 1 1 auto;
  min-width: 0;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: calc(100% / 3);
  gap: 0;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.sector-cap-row::-webkit-scrollbar { display: none }

/* Same form as the front page's service list (.svc-items): no box, no fill, just an icon, a label
   and a line of copy, with a hairline between columns. These were bordered, filled cards, which
   made six of them read as six objects competing with the project photography further down the
   page; the front-page treatment states the same content and stays quiet. The values are matched
   to .svc-items deliberately, so the two read as one component used in two places. */
.sector-cap-card {
  scroll-snap-align: start;
  padding-inline: clamp(1rem, 1.8vw, 2rem);
}

.sector-cap-card:first-child { padding-inline-start: 0 }
.sector-cap-card + .sector-cap-card { border-inline-start: 1px solid var(--line) }

.sector-cap-icon {
  display: block;
  width: clamp(1.8rem, 1.4rem + 1vw, 2.4rem);
  height: clamp(1.8rem, 1.4rem + 1vw, 2.4rem);
  margin-bottom: clamp(.9rem, 1.5vw, 1.5rem);
  fill: none;
  stroke: var(--navy);
  stroke-width: 1.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.sector-cap-card h4 {
  font-size: clamp(.95rem, .85rem + .4vw, 1.15rem);
  font-weight: 600;
  color: var(--navy);
  line-height: 1.2;
  margin-bottom: 0;
}

/* The front page runs four of these across 100rem, so its columns set the measure themselves.
   Three across a wider band would give lines about twice that long, so the copy carries its own. */
.sector-cap-card p {
  font-size: .85rem;
  line-height: 1.5;
  color: var(--ink-soft);
  margin-top: .4rem;
  max-width: 26ch;
}


/* Static "Meie teenused" / "Our services" block for sector archive pages (taxonomy-reference_type.php).
   Visually this is a faithful rebuild of the homepage's pinned #svcOuter component (tabs +
   progress dots + icon grid + photo band — see .svc-tabs etc. in home.css), under svc-static-*
   class names so it can run here without home.css's scroll-jacking rules (.svc-outer's
   height:360svh, .svc-sticky's position:sticky, and home.js's scroll-linked activation).
   Switching between the four steps is a plain click handler (see the inline script printed
   after the block in taxonomy-reference_type.php) — same look, zero scroll dependency. */
.svc-static-grid {
  display: grid;
  grid-template-columns: minmax(0, 0.84fr) minmax(0, 1.16fr);
  gap: clamp(2rem, 4vw, 5rem);
  align-items: start;
  margin-top: clamp(1.6rem, 2.5vw, 2.4rem);
}

.svc-static-card {
  position: relative;
  min-height: clamp(13rem, 20vw, 17rem);
}

.svc-static-meta {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  opacity: 0;
  visibility: hidden;
  transition: opacity .3s var(--ease), visibility 0s .3s;
}

.svc-static-meta.is-active {
  position: relative;
  left: auto;
  right: auto;
  top: auto;
  opacity: 1;
  visibility: visible;
  transition: opacity .4s var(--ease) .05s;
}

.svc-static-no {
  font-family: var(--fs);
  font-weight: 300;
  font-size: clamp(3rem, 2rem + 3.5vw, 5.5rem);
  line-height: .78;
  color: var(--navy);
  display: block;
}

.svc-static-pt {
  font-size: clamp(1.35rem, 1rem + 1.4vw, 2rem);
  font-weight: 400;
  letter-spacing: -0.02em;
  line-height: 1.12;
  margin-top: clamp(0.9rem, 1.6vw, 1.4rem);
  color: var(--navy);
  max-width: 16ch;
}

.svc-static-pl {
  font-size: .98rem;
  color: var(--ink-soft);
  line-height: 1.55;
  margin-top: .85rem;
  max-width: 40ch;
}

.svc-static-right {
  display: flex;
  flex-direction: column;
  gap: clamp(1.5rem, 2.5vw, 2.4rem);
}

.svc-static-tabs {
  position: relative;
  background: oklch(0.963 0.005 264);
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  padding: clamp(1rem, 1.5vw, 1.6rem) clamp(0.4rem, 0.8vw, 0.9rem) clamp(1.4rem, 1.9vw, 2.1rem);
}

.svc-static-tab {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: clamp(.8rem, 1.4vw, 1.2rem);
  background: none;
  border: none;
  cursor: pointer;
  padding: clamp(0.7rem, 1.2vw, 1.1rem) .4rem 0;
  color: var(--ink-soft);
  transition: color .3s var(--ease);
}

.svc-static-tab .lbl {
  font-size: clamp(.72rem, 0.6rem + 0.4vw, .92rem);
  letter-spacing: .12em;
  text-transform: uppercase;
  font-weight: 500;
  text-align: center;
  line-height: 1.35;
  min-height: 2.5em;
  display: flex;
  align-items: flex-start;
  justify-content: center;
}

.svc-static-tab .pip {
  width: 13px;
  height: 13px;
  border-radius: 50%;
  border: 1.5px solid oklch(0.62 0.03 264);
  position: relative;
  z-index: 2;
  background: oklch(0.963 0.005 264);
  transition: border-color .3s var(--ease);
}

.svc-static-tab .pip::after {
  content: "";
  position: absolute;
  inset: 2.5px;
  border-radius: 50%;
  background: var(--navy);
  transform: scale(0);
  transition: transform .3s var(--ease);
}

.svc-static-tab:hover { color: var(--navy); }
.svc-static-tab.is-active { color: var(--navy); }
.svc-static-tab.is-active .pip { border-color: var(--navy); }
.svc-static-tab.is-active .pip::after { transform: scale(1); }

.svc-static-track {
  position: absolute;
  left: 12.5%;
  right: 12.5%;
  bottom: calc(clamp(1.4rem, 1.9vw, 2.1rem) + 6px);
  height: 2px;
  background: var(--line);
  z-index: 1;
  transform: translateY(50%);
}

.svc-static-fill {
  height: 100%;
  width: 100%;
  background: var(--navy);
  transform-origin: left;
  transform: scaleX(0.25);
  transition: transform .4s var(--ease);
}

.svc-static-stack {
  position: relative;
  min-height: clamp(11rem, 18vw, 15rem);
}

.svc-static-items {
  list-style: none;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  position: absolute;
  inset: 0;
  opacity: 0;
  visibility: hidden;
  transition: opacity .3s var(--ease), visibility 0s .3s;
}

.svc-static-items.is-active {
  position: relative;
  opacity: 1;
  visibility: visible;
  transition: opacity .4s var(--ease) .05s;
}

.svc-static-items li { display: block; padding: 0 clamp(1rem, 1.8vw, 2rem); }
.svc-static-items li:first-child { padding-inline-start: 0; }
.svc-static-items li + li { border-inline-start: 1px solid var(--line); }

.svc-static-ic {
  display: block;
  color: var(--navy);
  line-height: 0;
  margin-bottom: clamp(0.9rem, 1.5vw, 1.5rem);
}

.svc-static-ic svg {
  width: clamp(1.8rem, 1.4rem + 1vw, 2.4rem);
  height: clamp(1.8rem, 1.4rem + 1vw, 2.4rem);
  stroke: var(--navy);
  fill: none;
  stroke-width: 1.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.svc-static-items h4 {
  font-size: clamp(0.95rem, 0.85rem + 0.4vw, 1.15rem);
  font-weight: 600;
  color: var(--navy);
  line-height: 1.2;
}

.svc-static-items p {
  font-size: .85rem;
  color: var(--ink-soft);
  line-height: 1.5;
  margin-top: .4rem;
}

.svc-static-img {
  position: relative;
  margin-top: clamp(1.5rem, 3vw, 2.4rem);
  height: clamp(13rem, 26vh, 22rem);
  overflow: hidden;
  background: var(--paper-2);
}

.svc-static-frame {
  position: absolute;
  inset: 0;
  opacity: 0;
  visibility: hidden;
  transition: opacity .4s var(--ease);
}

.svc-static-frame.is-active { opacity: 1; visibility: visible; }

.svc-static-img img { width: 100%; height: 100%; object-fit: cover; display: block; }

@media (max-width: 920px) {
  .svc-static-grid { grid-template-columns: 1fr; gap: clamp(2rem, 4vw, 3rem); }
  .svc-static-card { min-height: 0; }
  .svc-static-items { grid-auto-flow: row; grid-auto-columns: auto; }
  .svc-static-items li { padding: clamp(0.9rem, 3vw, 1.3rem) 0; }
  .svc-static-items li:first-child { padding-top: 0; }
  .svc-static-items li + li { border-inline-start: none; border-top: 1px solid var(--line); }
  .svc-static-meta { position: absolute; }
  .svc-static-meta.is-active { position: relative; }
  .svc-static-stack { min-height: 0; }
}

@media (max-width: 560px) {
  .svc-static-tab .lbl { font-size: .56rem; }
  .svc-static-items p { max-width: none; }
}

/* One lead item (16:9, the width of the row) and two smaller items sharing the second row —
   the same "1 large + 2 small" rhythm as the front-page project rail, so the pattern reads as
   the site's established way of showing project photography rather than a one-off. */
.sector-work-showcase {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(1rem, 2vw, 1.6rem);
  margin-bottom: clamp(3rem, 6vw, 6rem);
}

/* The index can be switched to a list or a gallery. The lead photographs belong to the grid
   reading of it, so they step aside rather than sitting on top of a different layout. */
.work-index:not([data-view="grid"]) .sector-work-showcase { display: none }

.sector-work-item { grid-column: span 1; display: block; color: inherit }
.sector-work-item.is-lead { grid-column: 1 / -1 }

.sector-work-shot {
  overflow: hidden;
  background: var(--paper-2);
  aspect-ratio: 16 / 10;
  margin-bottom: .9rem;
}

.sector-work-item.is-lead .sector-work-shot { aspect-ratio: 21 / 9 }

.sector-work-shot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 1.1s var(--ease);
}

.sector-work-item:hover .sector-work-shot img { transform: scale(1.04) }

.sector-work-cap .eyebrow { display: block; margin-bottom: .35rem }

.sector-work-cap h3 {
  display: inline;
  font-size: clamp(1.05rem, .95rem + .3vw, 1.3rem);
  font-weight: 400;
  color: var(--navy);
}

.sector-work-year { margin-inline-start: .6rem; font-size: .82rem; color: var(--ink-soft) }

/* The closing line and the solutions list, side by side, closing the body section. The copy above
   is two columns of text whose right-hand one runs short on every sector, which left a hole in the
   middle of the page; this row fills it. The closing line keeps its own rule above it, so the
   two columns each announce themselves rather than sharing one long line. */
.sector-body-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 5rem);
  align-items: start;
  margin-top: clamp(1.6rem, 3vw, 2.6rem);
}

.sector-sol-title {
  font-family: var(--f);
  font-size: clamp(.78rem, .72rem + .2vw, .9rem);
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin: 0 0 clamp(.8rem, 1.5vw, 1.2rem);
}

/* Stacked, not the six-across strip this used to be. In half the width of the page, six labels in
   a row would each get about 6rem — this is a list of what the sector needs, so it reads as one. */
.sector-sol-row {
  display: block;
  border-top: 1px solid var(--line);
}

.sector-sol-item {
  display: flex;
  align-items: center;
  gap: .8rem;
  padding: .8rem .1rem;
  border-bottom: 1px solid var(--line);
  color: inherit;
  transition: color .3s var(--ease);
}

a.sector-sol-item:hover { color: var(--navy) }
a.sector-sol-item:hover .sector-sol-icon { stroke: var(--navy) }

.sector-sol-icon {
  width: 1.9rem;
  height: 1.9rem;
  flex: 0 0 auto;
  fill: none;
  stroke: var(--ink-soft);
  stroke-width: 1.3;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: stroke .3s var(--ease);
}

.sector-sol-item span:not(.ar) {
  font-size: .85rem;
  font-weight: 600;
  letter-spacing: .01em;
}

.sector-sol-item .ar { margin-inline-start: auto }

@media (max-width: 900px) {
  .sector-cap-row { grid-auto-columns: 100% }
  /* One item per view, so the hairline between columns would land on the screen edge instead of
     between two things. The items are paged apart here; they do not need separating as well. */
  .sector-cap-card,
  .sector-cap-card:first-child { padding-inline: 0 }
  .sector-cap-card + .sector-cap-card { border-inline-start: 0 }
  .sector-work-showcase { grid-template-columns: 1fr }
  .sector-work-item.is-lead .sector-work-shot { aspect-ratio: 16 / 10 }
  /* Both tracks stack to one column below — there is nothing left to page through, so the two
     circular arrow buttons stop being controls and start being ~6rem of dead width squeezing an
     already-narrow column. Hide them; the dots stay as a plain progress indicator. */
  .showcase-nav { display: none }
  /* The closing line and the list stop competing for a half-width column and stack instead. */
  .sector-body-grid { grid-template-columns: 1fr; gap: clamp(1.8rem, 5vw, 2.6rem) }
}

/* ---- one left edge below the hero ----
 * A sector page stacked three of them. The hero and the sector switcher sit on --edge, the same
 * line as the logo — that is the full-bleed opener and it stays. Everything under it sat on the
 * wrap (--maxw, centred), except the reference index, which broke out wider still on its own
 * padding, so the page ran 262px, then 36px, then 262px again for the closing band. Nothing
 * overlapped; the eye simply had to re-find the left margin twice on the way down.
 *
 * The index runs wide when it *is* the page (/referentsid/), which is right there and wrong here:
 * on a sector page it is one section among several. Inside a sector page it keeps the same measure
 * as the sections above and below it. Scoped to the grid view — list and gallery have their own
 * deliberate padding and are left alone.
 */
.tax-reference_type .work-index[data-view="grid"] .work-grid {
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--edge);
}

/* The index heading is screen-reader-only by default, because on /referentsid/ the visible title
   is the <h1> in .work-intro above it. A sector page has no .work-intro, so once the highlighted
   projects moved into this section it became thirty-odd projects under a heading nobody could
   see. Here it is the section's real heading. */
.tax-reference_type .work-page-title {
  position: static;
  width: auto;
  height: auto;
  max-width: var(--maxw);
  margin: 0 auto clamp(1.4rem, 2.5vw, 2.4rem);
  padding-inline: var(--edge);
  overflow: visible;
  clip: auto;
  clip-path: none;
  white-space: normal;
  font-family: var(--fs);
  font-weight: 300;
  font-size: clamp(1.5rem, 1.1rem + 1.2vw, 2.2rem);
  line-height: 1.15;
  letter-spacing: -.02em;
  color: var(--navy);
}

/* Everything from the figures band down runs 20% wider than the site's default measure.
 * --maxw is 82rem site-wide; a sector page gets 98.4rem. It is set on <main> rather than on each
 * section because every block below the hero already reads it — the wrap, the contained reference
 * grid and the index heading — so one declaration moves them together and they cannot drift apart
 * later. The hero is inside <main> too but sits on --edge alone with no max-width, so it is
 * untouched and stays full-bleed. */
.tax-reference_type main { --maxw: 98.4rem }

/* Air between the sector switcher and the figures band.
 * The switcher is the closing edge of the full-height hero and the figures band opened straight
 * off it — a 0px gap, with only the band's own padding doing any separating. The hero needs to
 * finish before the page starts. */
.tax-reference_type .sector-figures { padding-top: clamp(4rem, 2.5rem + 4vw, 8.5rem) }

/* 3. A sector with no references yet points somewhere instead of apologising. */
.sector-empty {
  padding-block: clamp(2.5rem, 5vw, 5rem);
  max-width: 52rem;
}

.sector-empty p {
  font-size: clamp(1.05rem, 1rem + .4vw, 1.3rem);
  line-height: 1.55;
  color: var(--ink-soft);
}

.sector-empty-links {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(1rem, 3vw, 2.5rem);
  margin-top: clamp(1.4rem, 3vw, 2.2rem);
}

/* =====================================================================
 * SIPA as a case study — the proof block under the narrative.
 *
 * Four parts, each answering a different question: what was achieved (figures), who brought what
 * (the split), why it matters (the chain), and where it ends up (uses). The split is the one that
 * makes it a co-development story rather than a supplier story, so it gets the plus sign in the
 * middle and equal weight on both sides.
 * ================================================================== */
.lab-proof { padding-block: 0 clamp(3rem, 6vw, 6rem) }

/* --- The result, in three figures --- */
.lab-proof-figures {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: clamp(1.5rem, 3vw, 3rem);
  padding-block: clamp(2rem, 4vw, 3.5rem);
  border-top: 1px solid var(--d-line);
  border-bottom: 1px solid var(--d-line);
}

.lab-proof-figures strong {
  display: block;
  font-family: var(--fs);
  font-weight: 300;
  font-size: clamp(1.9rem, 1.3rem + 1.8vw, 3rem);
  line-height: 1;
  color: #fff;
}

.lab-proof-figures span {
  display: block;
  margin-top: .6rem;
  font-size: .85rem;
  line-height: 1.45;
  color: var(--d-text-soft);
  max-width: 24ch;
}

/* --- Who brought what --- */
.lab-proof-split {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: clamp(1.5rem, 4vw, 4rem);
  align-items: start;
  padding-block: clamp(2.5rem, 5vw, 4.5rem);
}

.lab-proof-who {
  display: block;
  font-size: .68rem;
  letter-spacing: .2em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--rust-soft);
  margin-bottom: 1rem;
}

.lab-proof-split ul { list-style: none; display: flex; flex-direction: column; gap: .6rem }

.lab-proof-split li {
  position: relative;
  padding-inline-start: 1.1rem;
  font-size: .95rem;
  line-height: 1.45;
  color: var(--d-text);
}

.lab-proof-split li::before {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  top: .64em;
  width: .45rem;
  height: 1px;
  background: var(--rust-soft);
}

.lab-proof-plus {
  font-family: var(--fs);
  font-size: clamp(1.5rem, 3vw, 2.4rem);
  font-weight: 300;
  color: var(--rust);
  line-height: 1;
  padding-top: 1.4rem;
}

/* --- Why weight matters, as a chain --- */
.lab-proof-chain-lbl {
  display: block;
  font-size: .68rem;
  letter-spacing: .2em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--rust-soft);
  margin-bottom: 1.2rem;
}

.lab-proof-chain { padding-block: clamp(2rem, 4vw, 3.5rem); border-top: 1px solid var(--d-line) }

.lab-proof-chain ol {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(.6rem, 1.5vw, 1.4rem);
}

.lab-proof-chain li {
  position: relative;
  padding-top: 1.5rem;
  font-size: .92rem;
  line-height: 1.35;
  color: #fff;
}

/* The rail and its nodes, drawn the same way as the flow diagram above so the page has one
   visual language for "this leads to that". */
.lab-proof-chain li::before {
  content: "";
  position: absolute;
  top: .28rem;
  inset-inline-start: 0;
  width: .45rem;
  height: .45rem;
  border-radius: 50%;
  background: var(--rust);
}

.lab-proof-chain li:not(:last-child)::after {
  content: "";
  position: absolute;
  top: .5rem;
  inset-inline-start: .75rem;
  inset-inline-end: -.6rem;
  height: 1px;
  background: var(--rust-soft);
  opacity: .5;
}

/* --- Where it is used --- */
.lab-proof-uses { padding-block: clamp(2rem, 4vw, 3.5rem) 0; border-top: 1px solid var(--d-line) }

.lab-proof-uses > div {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: clamp(1.5rem, 3vw, 3rem);
}

.lab-proof-uses h4 {
  font-size: 1.05rem;
  font-weight: 400;
  color: #fff;
  margin-bottom: .5rem;
}

.lab-proof-uses p { font-size: .9rem; line-height: 1.5; color: var(--d-text-soft); max-width: 30ch }

@media (max-width: 760px) {
  .lab-proof-split { grid-template-columns: 1fr; gap: 2rem }
  .lab-proof-plus { display: none }
  .lab-proof-chain ol { grid-template-columns: 1fr; gap: 1rem; padding-inline-start: 1.4rem }
  .lab-proof-chain li { padding-top: 0 }
  .lab-proof-chain li::before { top: .42em; inset-inline-start: -1.4rem }
  /* Vertical rail on phones, matching the flow diagram's mobile behaviour. */
  .lab-proof-chain li:not(:last-child)::after {
    top: 1.1em; bottom: -1rem; inset-inline: -1.18rem auto;
    width: 1px; height: auto;
  }
}

/* ==================================================================
 * Standard Lab — the case slider
 *
 * "Herosid on veel neid peaks äkki slider tegema mis avalehel ka sarnane nagu?"
 *
 * Shaped after the homepage hero on purpose — full-bleed photograph, one large line over it, arrows
 * bottom-right, dots bottom-left — but built from scratch. The homepage component is welded to the
 * GSAP stage timeline and the deck panels beneath it, and none of that belongs on this page.
 *
 * Update: the brief changed — this slider now goes full-bleed and is set to a fixed height (60%
 * of the viewport) instead of the inset 16:9 box described above, so it reads as a second hero
 * beat on the page rather than a contained module.
 * ================================================================== */
.lab-cases {
  /* Edge to edge, and the photograph owns the whole band. The white padding and the framed inset it
     used to have are gone on review: "full width see pilt". */
  background: var(--d-bg-2);
  padding-block: 0;
}

.lab-cases-head.lc-over {
  position: absolute;
  z-index: 2;
  inset: clamp(2rem, 5vw, 4.5rem) var(--edge) auto;
  max-width: var(--maxw);
  margin-inline: auto;
  pointer-events: none;   /* never blocks the arrows or the slide link underneath */
}
.lab-cases-head .eyebrow { display: block; color: rgba(255,255,255,.72) }

.lab-cases-head h2 {
  margin-top: .7rem;
  font-size: clamp(2rem, 1.2rem + 3vw, 4rem);
  font-weight: 400;
  line-height: 1.02;
  letter-spacing: -.02em;
  color: #fff;
  max-width: 18ch;
}

.lab-cases-head > p { margin-top: .9rem; max-width: 62ch; color: rgba(255,255,255,.92); line-height: 1.6 }

.lab-cases-head > p {
  /*
   * White, not --ink-soft. This block used to sit on the white page above the slider; it is laid over
   * the photograph now, and the muted grey was invisible on a light frame. Note there is an earlier
   * rule with this same selector — equal specificity, so the later one wins and the colour has to be
   * set here rather than there.
   */
  margin-top: .9rem;
  max-width: 46ch;
  color: rgba(255,255,255,.92);
  line-height: 1.6;
}

.lc-track {
  position: relative;
  overflow: hidden;
  background: var(--d-tile);
  /* Full-bleed. The framed version was tried and rejected — with the heading now sitting on the
     photograph, an inset frame would put a border between a title and its own picture. */
  width: 100%;
  max-width: none;
  margin: 0;
  height: clamp(32rem, 84svh, 52rem);
  border: 0;
  box-shadow: none;
}

/* On a phone the frame costs more than it gives: keep the inset, drop the height to something a
   portrait screen can hold. */
@media (max-width: 700px) {
  .lc-track { height: auto; aspect-ratio: 4 / 5 }
}

/*
 * Cross-fade. Every slide is stacked in the same grid cell, so the track's height is fixed by the
 * aspect ratio and never changes as slides swap — a block that resizes mid-scroll is exactly what
 * caused the mobile scroll glitch in the services section, and it is not being repeated here.
 */
.lc-slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  visibility: hidden;
  transition: opacity .6s ease, visibility .6s;
}

.lc-slide.on { opacity: 1; visibility: visible }

.lc-bg { position: absolute; inset: 0 }
.lc-bg img { width: 100%; height: 100%; object-fit: cover; display: block }

/*
 * The scrim. White text over an uncontrolled photograph is a legibility gamble; this makes it a
 * decision. Weighted to the bottom because that is where the copy sits.
 */
.lc-slide::after {
  content: "";
  position: absolute;
  inset: 0;
  /*
   * Two gradients, not one.
   *
   * The bottom one has always been there, for the case title. The top one was added once the section
   * heading moved onto the photograph: on a light frame of the SIPA panel the intro line under
   * "Koostööprojektid" simply disappeared. Weighting both ends and leaving the middle almost clear
   * keeps the picture readable as a picture while both blocks of text stay legible on any slide —
   * which matters because the photographs come from posts and nobody is checking their brightness.
   */
  background:
    linear-gradient(to bottom, oklch(0.16 0.04 264 / .78) 0%, oklch(0.16 0.04 264 / .30) 28%, transparent 46%),
    linear-gradient(to top, oklch(0.16 0.04 264 / .92) 0%, oklch(0.16 0.04 264 / .55) 45%, oklch(0.16 0.04 264 / .10) 100%);
}

.lc-in {
  /* Clear of the section heading overlaid at the top. */
  padding-top: clamp(11rem, 24vw, 18rem);
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding-block: clamp(1.6rem, 4vw, 3.4rem);
  /* Room for the dots and arrows that sit on the same baseline. */
  padding-bottom: clamp(4.4rem, 7vw, 6rem);
}

.lc-meta {
  display: flex;
  flex-wrap: wrap;
  gap: .55rem 1rem;
  align-items: center;
  font-size: var(--fs-eyebrow);
  letter-spacing: .18em;
  text-transform: uppercase;
  font-weight: 700;
  color: rgba(255,255,255,.82);
}

/* The status is a fact, not a label — a hairline box keeps it from competing with the partner name. */
.lc-status {
  border: 1px solid rgba(255,255,255,.35);
  border-radius: 999px;
  padding: .25rem .7rem;
  letter-spacing: .12em;
}

.lc-title {
  /*
   * Capped at three lines, hard.
   *
   * Review note: "natuke kirju on." The cause was that these titles are post titles, and post titles
   * are sentences — the Kai Stania one ran to six lines, grew upward and collided with the section
   * intro above it, so two unrelated blocks of text met in the middle with nothing between them.
   *
   * Clamping is the right fix rather than shorter headlines, because the copy lives in the blog and
   * the person writing a post is not thinking about this slide. Three lines is enough to carry any
   * of them; the rest is what the case study page is for.
   */
  margin-top: .9rem;
  font-size: clamp(1.5rem, .9rem + 1.8vw, 2.5rem);
  font-weight: 400;
  line-height: 1.08;
  letter-spacing: -.02em;
  color: #fff;
  max-width: 18ch;

  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.lc-in > p {
  /* Two lines. The excerpt is a teaser, not the article — five lines of it was the other half of the
     clutter, and it pushed the link off the bottom of the readable area. */
  margin-top: .8rem;
  max-width: 46ch;
  color: rgba(255,255,255,.82);
  line-height: 1.6;

  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.lc-in .arrow-link { color: #fff; margin-top: clamp(1rem, 2vw, 1.6rem) }

/* Hide the supporting paragraph on the narrowest screens: the headline and the link are the slide. */
@media (max-width: 560px) {
  .lc-in > p { display: none }
}

.lc-nav {
  position: absolute;
  z-index: 2;
  right: var(--edge);
  bottom: clamp(1.4rem, 3vw, 2.4rem);
  display: flex;
  gap: .5rem;
}

.lc-nav .s-btn {
  width: 2.9rem;
  height: 2.9rem;
  display: grid;
  place-items: center;
  border: 1px solid rgba(255,255,255,.4);
  border-radius: 50%;
  background: rgba(0,0,0,.2);
  color: #fff;
  cursor: pointer;
  transition: background .25s ease, border-color .25s ease;
}

.lc-nav .s-btn:hover { background: rgba(255,255,255,.16); border-color: rgba(255,255,255,.8) }
.lc-nav .s-btn:focus-visible { outline: 2px solid #fff; outline-offset: 2px }

.lc-dots {
  position: absolute;
  z-index: 2;
  left: var(--edge);
  bottom: clamp(1.4rem, 3vw, 2.4rem);
  display: flex;
  gap: .5rem;
}

.lc-dots button {
  width: 2.2rem;
  height: 3px;
  border: 0;
  padding: 0;
  background: rgba(255,255,255,.32);
  cursor: pointer;
  transition: background .25s ease;
}

.lc-dots button.on { background: #fff }
.lc-dots button:focus-visible { outline: 2px solid #fff; outline-offset: 4px }

/* Someone who has asked for less motion gets the slides swapped, not dissolved. */
@media (prefers-reduced-motion: reduce) {
  .lc-slide { transition: none }
}

/* ==================================================================
 * Standard Lab — the seven-step scroll
 *
 * "tahaks teha scroll põhiseks et sa pead selle läbi tegema ja laiemaks ja info suuremaks."
 *
 * All three asks are structural, not cosmetic. Wider: this breaks out of --maxw to 100rem, the same
 * measure the homepage services section uses, so the site's two scroll-driven sections share a
 * width. Bigger: one step on screen at a time is what lets the type be display-sized instead of
 * list-sized, which is the whole reason to do this rather than print seven paragraphs.
 *
 * Height comes from --steps, set in the template from the ACF row count, so an eighth step
 * lengthens the scroll on its own and nobody has to come back here and change a number.
 * ================================================================== */
/* ==================================================================
 * Standard Lab — the seven steps, as a horizontal accordion
 *
 * "See slideri osa võiks olla selline nagu umbes visuaal on et need on nagu kaardid."
 *
 * Seven cards side by side. The open one takes the room it needs; the rest collapse to a spine with
 * the number at the top, the name set vertically, and a button to open it.
 *
 * Why this beats the cross-fade it replaces: fading one panel in over another shows the reader where
 * they are but never what is around them. Cards make the whole process visible at once — you can see
 * that there are seven, which are behind you, and how far there is to go — while still only asking
 * you to read one at a time. For a process section that is the entire point.
 *
 * Driven by hover/focus on wide screens (see lab.js); phones keep the full stacked list.
 * ================================================================== */
.lab-steps {
  /*
   * Light section, on a dark page. Flipped on review: "tee see sektsioon valge taustaga".
   *
   * Worth knowing why every colour below is written out rather than inherited: the block was built
   * dark, so its rules all named white and rgba(255,255,255,...) explicitly. Changing the background
   * alone would have left seven cards of white text on white. The palette is now the site's paper
   * set, which also means the process reads as a bright, matter-of-fact passage between two dark
   * bands — which is what a list of practical steps should feel like next to the photography.
   */
  position: relative;
  background: var(--paper);
}

/* Without JS this is an ordinary stacked list. With JS it becomes one self-contained accordion,
   not a multi-screen scroll track. */
.lab-steps.is-steps { height: auto }

.lab-steps-sticky { padding-block: clamp(3rem, 6vw, 6rem) }
.lab-steps.is-steps .lab-steps-sticky {
  position: relative; top: auto; min-height: 100svh;
  display: flex; align-items: center; padding-block: clamp(3rem, 6vw, 6rem);
}

.lab-steps-in { width: 100%; max-width: 100rem; margin-inline: auto; padding-inline: var(--edge) }

.lab-steps-head .eyebrow { display: block; color: var(--ink-soft) }
.lab-steps-head h2 {
  margin-top: .8rem; font-size: clamp(1.5rem, 1rem + 1.8vw, 2.6rem); font-weight: 400;
  line-height: 1.06; letter-spacing: -.015em; color: var(--navy); max-width: 22ch;
}

/*
 * The old number rail is gone. Every card now carries its own number and name, so a separate row of
 * 01–07 above them was the section stating its structure twice — the same redundancy the four-word
 * definition list had before it.
 */
.lab-steps-rail { display: none }

/* ---- the card row ---- */
.lab-steps.is-steps .lab-steps-panels {
  display: flex;
  gap: clamp(.35rem, .7vw, .8rem);
  margin-top: clamp(1.5rem, 3vw, 2.6rem);
  /* Shorter than the first attempt: with no illustration inside, a taller card is just a void under
     the paragraph. Sized to the text it actually holds. */
  height: clamp(19rem, 31vw, 25rem);
  list-style: none;
  padding: 0;
}

/* The open card lays out as a column so the body takes the leftover space instead of leaving it. */
.lab-steps.is-steps .lab-step.on { display: flex; flex-direction: column }
.lab-steps.is-steps .lab-step.on .lab-step-body {
  /*
   * A fixed width, not a fluid one.
   *
   * Without it the paragraph re-wraps continuously while the card narrows, so for the whole 0.65s of
   * the close you watch the previous step's text reflow into a two-character column before it
   * vanishes. Laying it out once at full width and letting overflow:hidden crop it as the card
   * shrinks is what makes the card look like it is sliding shut rather than being crushed.
   */
  width: min(34rem, 46vw);
  max-width: 100%;
  margin-top: clamp(1.2rem, 3vw, 2.4rem);
  opacity: 0;
  visibility: hidden;
  /* Leaves fast. A closing card should be empty before it is narrow. */
  transition: opacity .16s var(--ease), visibility 0s .16s;
}

.lab-steps.is-steps .lab-step {
  position: relative;
  flex: 0 0 clamp(3rem, 4.4vw, 4.6rem);
  min-width: 0;
  background: var(--paper-2);
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
  padding: clamp(1rem, 1.8vw, 1.6rem);
  opacity: 1;
  visibility: visible;
  transform: none;
  /* Only flex-basis animates. Nothing here changes the row's height, ever. */
  transition: flex-basis .65s var(--ease), background .45s var(--ease);
  cursor: pointer;
}

.lab-steps.is-steps .lab-step:focus-visible { outline: 2px solid var(--navy); outline-offset: 3px }

.lab-steps.is-steps .lab-step.on {
  flex: 1 1 auto;
  background: var(--paper-2);
  border-color: var(--line);
}

/* Completed cards read as spent rather than pending. */
/* Completed cards read as spent rather than pending. */
.lab-steps.is-steps .lab-step.done { background: color-mix(in oklch, var(--paper-2) 55%, var(--paper)) }

.lab-step-n {
  display: block;
  font-family: var(--fs);
  font-weight: 300;
  font-size: clamp(.8rem, .7rem + .3vw, 1rem);
  line-height: 1;
  letter-spacing: .14em;
  color: var(--ink-soft);
  transition: color .45s var(--ease), font-size .65s var(--ease);
}

.lab-steps.is-steps .lab-step.on .lab-step-n {
  font-size: clamp(1.6rem, 1rem + 1.6vw, 2.4rem);
  letter-spacing: 0;
  color: var(--rust, var(--rust-soft));
}

/* ---- collapsed: the spine ---- */
.lab-step-spine {
  /*
   * inset on all four sides, not inset-inline-start + translate.
   *
   * An absolutely positioned box resolves its insets against the *containing block's* writing mode,
   * not its own, so pinning only the start edge and letting a vertical-rl element size itself gave a
   * width of exactly 0 — the label was there, correct, and clipped to nothing by overflow:hidden.
   * Giving it the card's full width and centring inside is simpler and immune to that.
   */
  position: absolute;
  inset: clamp(2.6rem, 4vw, 3.4rem) 0 clamp(1.4rem, 2.4vw, 2rem);
  display: flex;
  align-items: center;
  justify-content: center;
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  font-size: clamp(.62rem, .56rem + .2vw, .76rem);
  letter-spacing: .2em;
  text-transform: uppercase;
  white-space: nowrap;
  overflow: hidden;
  color: var(--ink-soft);
  transition: opacity .3s var(--ease);
}

.lab-steps.is-steps .lab-step.on .lab-step-spine { opacity: 0; pointer-events: none }

/* ---- open: the content ---- */
.lab-step-body {
  margin-top: clamp(1.2rem, 3vw, 2.4rem);
  opacity: 0;
  visibility: hidden;
  transition: opacity .35s var(--ease), visibility 0s .35s;
}

.lab-steps.is-steps .lab-step.on .lab-step-body {
  opacity: 1;
  visibility: visible;
  transition: opacity .5s var(--ease) .25s;  /* waits for the card to finish opening */
}

.lab-step-body h3 {
  font-size: clamp(1.5rem, 1rem + 2.2vw, 3rem);
  font-weight: 400; line-height: 1.04; letter-spacing: -.02em;
  color: var(--navy); max-width: 16ch;
}

.lab-step-body p {
  margin-top: clamp(.8rem, 1.5vw, 1.2rem);
  font-size: clamp(1rem, .92rem + .4vw, 1.3rem);
  line-height: 1.55; color: var(--ink-soft); max-width: 42ch;
}

/* ---- the photograph on the open card ---- */

/*
 * Absolutely positioned, not a grid column.
 *
 * A grid column would resize as the card opens and shuts, and the body text beside it would re-wrap
 * for the whole animation — the exact problem the fixed body width was introduced to solve. Taking
 * the picture out of flow keeps the text laid out once and lets the card's overflow:hidden crop both
 * as it narrows.
 */
.lab-step-img {
  /*
   * Absolutely positioned, not a grid column.
   *
   * A grid column would resize as the card opens and shuts, and the body text beside it would re-wrap
   * for the whole animation — the exact problem the fixed body width was introduced to solve. Taking
   * the picture out of flow keeps the text laid out once and lets overflow:hidden crop both.
   *
   * And no transition on it, deliberately. Two attempts to fade the picture in both froze: the
   * opacity transition would start, reach about 25ms and stop, leaving the photograph invisible on a
   * fully open card. Opacity transitions run on the compositor, and inside this page — where GSAP
   * drives the document with a transform and .page is position:fixed — that layer stops being ticked
   * and the transition never advances. The card opening carries the eye well enough without it, and
   * a picture that reliably appears beats one that elegantly does not.
   */
  position: absolute;
  inset: 0 0 0 auto;
  width: 46%;
  margin: 0;
  opacity: 0;
  pointer-events: none;
  transition: none;
}

.lab-steps.is-steps .lab-step.on .lab-step-img { opacity: 1; pointer-events: auto }

.lab-step-img img { width: 100%; height: 100%; object-fit: cover; display: block }

/*
 * With a picture the text gets a narrower fixed measure so the two never meet. Fixed in vw rather
 * than a percentage of the card, because a percentage would change while the card animates and we
 * would be back to re-wrapping text.
 */
.lab-steps.is-steps .lab-step.on.has-img .lab-step-body { width: min(28rem, 34vw) }

/* A card whose photo has not been filled in yet keeps the full width for its text. */

.lab-steps-bar {
  margin-top: clamp(1.2rem, 2.2vw, 1.8rem);
  height: 2px; background: var(--line); overflow: hidden;
}
.lab-steps-bar span { display: block; height: 100%; background: var(--navy); transform: scaleX(0); transform-origin: left center }

/*
 * Phones: no pinning, no accordion. Seven cards side by side needs horizontal room that a phone does
 * not have, so it becomes seven stacked blocks. The JS checks this same 901px breakpoint and does
 * nothing below it, so there is one number and both sides agree on it.
 */
@media (max-width: 900px) {
  .lab-steps.is-steps { height: auto }
  .lab-steps.is-steps .lab-steps-sticky { position: static; min-height: 0; display: block; padding-block: clamp(3rem, 8vw, 5rem) }
  .lab-steps.is-steps .lab-steps-panels { display: block; height: auto }
  .lab-steps.is-steps .lab-step {
    flex: none; padding: clamp(1.4rem, 5vw, 2rem) 0; background: none; border-radius: 0;
    border-top: 1px solid var(--line);
  }
  .lab-steps.is-steps .lab-step.done { background: none }
  .lab-step-spine, .lab-steps-bar { display: none }
  .lab-step-img {
    position: static; width: 100%; opacity: 1; pointer-events: auto;
    margin-top: clamp(1rem, 3vw, 1.4rem); aspect-ratio: 16 / 10;
  }
  .lab-steps.is-steps .lab-step.on.has-img .lab-step-body { width: auto }
  .lab-step-body { opacity: 1; visibility: visible; margin-top: .6rem }
  .lab-step-n { font-size: 1rem !important; color: var(--rust, var(--rust-soft)) }
}

@media (prefers-reduced-motion: reduce) {
  .lab-steps.is-steps .lab-step,
  .lab-step-body { transition-duration: .01s }
}


/* ==================================================================
 * Standard Lab — the enquiry, as a guided form
 *
 * Inline in the page, not an overlay. It was an overlay first and was rejected on review: a form
 * behind a button is a door someone has to decide to open, and on a page arguing "bring us your
 * idea" that is the wrong shape. Sitting at the end of the page it is simply visible.
 *
 * Everything here styles Gravity Forms' own markup rather than a copy of it. lab.js moves the real
 * fields into this shell, so these selectors deliberately reach into .gfield / .gfield_radio —
 * there is one set of inputs on the page and this is it.
 * ================================================================== */
.lab-wiz {
  display: grid;
  grid-template-columns: minmax(0, .72fr) minmax(0, 1.28fr);
  margin-top: clamp(1.6rem, 3vw, 2.6rem);
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
  background: var(--paper);
  text-align: left;
}

.lab-wiz [hidden] { display: none !important }

/* ---- left: photograph and the running summary ---- */
.lab-wiz-side { display: flex; flex-direction: column; background: var(--d-bg-2); min-height: 26rem }
.lab-wiz-photo { position: relative; flex: 1 1 auto; overflow: hidden; min-height: 8rem }
.lab-wiz-photo img { width: 100%; height: 100%; object-fit: cover; opacity: .45 }

/*
 * The summary is the point of the layout: it turns answering into building something rather than
 * emptying a queue. "määramata" going from grey italic to solid is the only feedback the form gives
 * before it is sent, and it is worth a column.
 */
.lab-wiz-read { flex: 0 0 auto; padding: clamp(1.1rem, 2vw, 1.5rem); display: grid; gap: .6rem }
.lab-wiz-read div { display: grid; gap: .1rem }
.lab-wiz-read span {
  font-size: var(--fs-eyebrow); letter-spacing: .16em; text-transform: uppercase;
  color: rgba(255,255,255,.42);
}
.lab-wiz-read strong { font-weight: 400; font-size: .92rem; line-height: 1.35; color: #fff }
.lab-wiz-read strong.pending { color: rgba(255,255,255,.3); font-style: italic }

/* ---- right: the questions ---- */
.lab-wiz-main { display: flex; flex-direction: column; min-width: 0; padding: clamp(1.4rem, 2.6vw, 2.2rem) }
.lab-wiz-main form { display: contents }

.lab-wiz-head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem }
.lab-wiz-crumbs { display: flex; flex-wrap: nowrap; overflow: hidden; gap: .2rem .8rem; min-width: 0 }
.lab-wiz-crumbs b {
  font-size: var(--fs-eyebrow); letter-spacing: .14em; text-transform: uppercase;
  font-weight: 500; color: var(--ink-soft); opacity: .4; white-space: nowrap;
}
.lab-wiz-crumbs b.done { opacity: .7 }
.lab-wiz-crumbs b.on { opacity: 1; color: var(--navy); font-weight: 700 }
.lab-wiz-count { font-size: .8rem; color: var(--ink-soft); white-space: nowrap }

.lab-wiz-bar { margin-top: .8rem; height: 2px; background: var(--line) }
.lab-wiz-bar i { display: block; height: 100%; width: 16%; background: var(--navy); transition: width .35s var(--ease) }

/* A fixed floor, so stepping between a six-card screen and a two-field one does not make the whole
   block jump up and down the page. */
.lab-wiz-stage { flex: 1 1 auto; min-height: 18rem; padding-block: clamp(1.2rem, 2.4vw, 1.8rem) }
.lab-wiz-scene > h3 {
  font-size: clamp(1.3rem, 1rem + 1.1vw, 1.9rem); font-weight: 400; line-height: 1.1;
  letter-spacing: -.015em; color: var(--navy); margin-bottom: clamp(.9rem, 2vw, 1.3rem);
}

/* GF chrome that does not belong in a one-question-per-screen layout. */
.lab-wiz .gfield > .gfield_label { display: none }
.lab-wiz .gform_footer { margin: 0; padding: 0 }
.lab-wiz .gfield { margin-bottom: clamp(1rem, 2vw, 1.5rem) }
.lab-wiz .gfield_description { font-size: .85rem; color: var(--ink-soft); margin-bottom: .7rem; padding: 0 }

/* One screen asks two things (maht + ajakava); label the second so it is not an unmarked list. */
.lab-wiz-scene .gfield + .gfield > .gfield_label {
  display: block; font-size: .85rem; color: var(--ink-soft); margin-bottom: .5rem; font-weight: 500;
}

/* ---- choices as cards ---- */
.lab-wiz .gfield_radio, .lab-wiz .gfield_checkbox {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); gap: .55rem;
}
.lab-wiz .gchoice { position: relative; margin: 0 }
.lab-wiz .gchoice input { position: absolute; opacity: 0; pointer-events: none }
.lab-wiz .gchoice label {
  display: block; padding: clamp(.8rem, 1.6vw, 1rem);
  border: 1px solid var(--line); border-radius: 8px;
  background: var(--paper-2); color: var(--navy);
  font-size: .95rem; line-height: 1.35; cursor: pointer;
  transition: border-color .2s var(--ease), background .2s var(--ease), color .2s var(--ease);
}
.lab-wiz .gchoice label:hover { border-color: var(--navy) }
.lab-wiz .gchoice input:checked + label { border-color: var(--navy); background: var(--navy); color: #fff }
.lab-wiz .gchoice input:focus-visible + label { outline: 2px solid var(--navy); outline-offset: 2px }

/* ---- free text ---- */
.lab-wiz .ginput_container input[type=text],
.lab-wiz .ginput_container input[type=email],
.lab-wiz .ginput_container input[type=tel],
.lab-wiz .ginput_container textarea {
  width: 100%; padding: .75rem .9rem;
  border: 1px solid var(--line); border-radius: 6px;
  background: var(--paper-2); color: var(--navy); font: inherit; font-size: .95rem;
}
.lab-wiz .ginput_container textarea { min-height: 7.5rem; resize: vertical }
.lab-wiz .ginput_container input:focus, .lab-wiz .ginput_container textarea:focus {
  outline: none; border-color: var(--navy);
}

.lab-wiz-missing .gchoice label,
.lab-wiz-missing .ginput_container input,
.lab-wiz-missing .ginput_container textarea { border-color: var(--rust, #b5502a) }

/* ---- actions ---- */
.lab-wiz-acts {
  flex: 0 0 auto; display: flex; align-items: center; gap: 1rem;
  padding-top: clamp(.9rem, 2vw, 1.2rem); border-top: 1px solid var(--line);
}
.lab-wiz-acts .lab-wiz-next, .lab-wiz .gform_footer { margin-inline-start: auto }
.lab-wiz-acts .btn.ghost { background: none; color: var(--ink-soft); border: 1px solid var(--line) }
.lab-wiz-err { color: var(--rust, #b5502a); font-size: .85rem; margin: 0 }
.lab-wiz .gform_button { cursor: pointer }

/* ---- phones: one column, the photograph gives way to the summary ---- */
@media (max-width: 780px) {
  .lab-wiz { grid-template-columns: 1fr }
  .lab-wiz-side { min-height: 0 }
  .lab-wiz-photo { display: none }
  .lab-wiz-read { grid-template-columns: repeat(2, minmax(0,1fr)); gap: .4rem .9rem }
  .lab-wiz-crumbs { display: none }
}

/*
 * Undo what the site stylesheet does to lists.
 *
 * Gravity Forms renders each choice as a .gchoice row, and the theme gives rows a top rule and
 * padding — which drew a hairline above every card and a stripe across the grid. Same reason the
 * scene needed its spacing zeroed: these are section and list elements borrowed into a component
 * that wants neither.
 */
.lab-wiz .gfield_radio, .lab-wiz .gfield_checkbox { list-style: none; margin: 0; padding: 0 }
.lab-wiz .gchoice { border: 0; padding: 0; margin: 0; list-style: none; display: block }
.lab-wiz-scene { margin: 0; padding: 0 }
.lab-wiz-scene > h3 { margin-top: 0 }
.lab-wiz .gfield { border: 0; padding: 0 }

/*
 * Two corrections to the enquiry panel, both from review.
 *
 * 1. The giant "LAB" watermark is gone: "see on kole ja las taust olla lihtsalt valge". It is set
 *    in base.css, which tools/sync-assets.py regenerates from the prototype, so it is switched off
 *    here rather than deleted there — edit base.css and the next sync brings it back.
 *
 *    It also earned its removal. A decorative word at 336px behind a form is the page admiring
 *    itself at the exact moment it is asking someone to concentrate.
 *
 * 2. Every field on a multi-field screen gets its label back. The rule that hid labels was written
 *    for one-question screens, where the <h3> already says what is being asked; on the contact
 *    screen it left the first box unlabelled — "siin on nimi tag puudu, ei saa aru mis field on".
 */
.lab-cta > div::after { content: none !important }
.lab-cta > div { background: var(--paper) }

.lab-wiz-scene:has(.gfield + .gfield) .gfield > .gfield_label {
  display: block;
  font-size: .85rem;
  color: var(--ink-soft);
  margin-bottom: .5rem;
  font-weight: 500;
}


/* ==================================================================
 * Home deck — one label per card, in one place
 *
 * Review note: "on the Sisustus part why is there 2 different headers. Dont you have some kind of
 * main place where u put the text how is there 2".
 *
 * The honest answer is that there was not one place. A card carries its name in up to three
 * elements — .seg-cap from the original build, .desktop-card-label added later, and a
 * .desktop-label-row from a third attempt — and the rules that show and hide them are scoped to
 * .panel.***.on. The deck moves through states, so in one state you saw one label and in another
 * you saw two. That is not a styling preference, it is three half-finished passes coexisting.
 *
 * This block settles it: exactly one visible label per card, in the same place in both panels,
 * and deliberately NOT scoped to .on so the answer cannot change with the deck state. !important
 * throughout because home.css uses it on every one of these rules and would otherwise win.
 *
 * Desktop only. The phone layout was reworked separately and is not touched.
 * ================================================================== */
@media (min-width: 901px) {

  /* ---- Sisustus: keep .desktop-card-label, silence the other two ---- */
  .p-segments .desktop-label-row { display: none !important }
  /* .seg-cap peideti siin varem, sest home.js lisas oma sildi. See silt oli koodi sisse
    kirjutatud eesti keeles ega tolkinud. Nuud on .seg-cap ainus kaardi pealkiri ja
    tuleb WordPressist; kujundus on home.css-i lopus. */

  .p-segments .cell { display: flex !important; flex-direction: column !important }
  .p-segments .cell .desktop-card-label {
    display: flex !important;
    order: -1 !important;
    align-items: center !important;
    justify-content: flex-start !important;
    gap: .7rem !important;
    text-align: left !important;
    margin-bottom: clamp(.6rem, 1vw, .9rem) !important;
  }

  /* ---- Tooted: same shape. The arrow becomes part of the label rather than a separate
       element floating above it, which is what made the two panels read differently. ---- */
  .p-products .cell { display: flex !important; flex-direction: column !important }
  .p-products .cell .k-label { display: none !important }
  .p-products .cell .go { display: none !important }

  .p-products .cell .meta {
    order: -1 !important;
    display: flex !important;
    flex-direction: row !important;
    align-items: center !important;
    justify-content: flex-start !important;
    gap: .7rem !important;
    text-align: left !important;
    margin-bottom: clamp(.6rem, 1vw, .9rem) !important;
  }

  .p-products .cell .meta::before {
    content: "\2192";
    flex: 0 0 auto;
    color: var(--navy);
  }
}

/* Sector landing pages: let the mobile hero follow its content instead of squeezing it into one screen. */
@media (max-width:640px) {
  .tax-reference_type .sector-subhero {
    height:auto;
    min-height:0;
    padding:2.5rem var(--edge) 0;
    overflow:visible;
  }

  .tax-reference_type .sector-subhero > div,
  .tax-reference_type .sector-subhero-main,
  .tax-reference_type .sector-subhero-right {
    display:block;
    height:auto;
    min-height:0;
  }

  .tax-reference_type .sector-subhero-main {
    padding-bottom:0;
  }

  .tax-reference_type .sector-subhero-copy {
    margin-bottom:1.5rem;
  }

  .tax-reference_type .sector-subhero h1 {
    font-size:clamp(2.8rem,12vw,4.2rem);
    line-height:.96;
  }

  .tax-reference_type .sector-subhero-copy p {
    font-size:1rem;
    line-height:1.5;
  }

  .tax-reference_type .sector-subhero-right {
    margin-top:1.5rem;
  }

  .tax-reference_type .sector-subhero-media {
    display:grid;
    height:clamp(11rem,50vw,13rem);
    min-height:0;
  }

  .tax-reference_type .sector-figures {
    grid-template-columns:repeat(3,minmax(0,1fr));
    gap:.75rem;
    padding:1.75rem 0 2rem;
  }

  .tax-reference_type .sector-figures strong {
    font-size:clamp(1.8rem,8vw,2.35rem);
  }

  .tax-reference_type .sector-figures span {
    max-width:12ch;
    margin-top:.4rem;
    font-size:.66rem;
    line-height:1.35;
  }

  .tax-reference_type .sector-subnav {
    margin-top:2rem;
  }

  .tax-reference_type .sector-figures + .sector-subnav {
    margin-top:0;
  }

  .tax-reference_type .sector-subnav a {
    gap:.35rem;
    padding:1rem .25rem;
    font-size:.6rem;
  }

  .tax-reference_type .sector-subnav svg {
    width:1.35rem;
    height:1.35rem;
  }
}

/* [taastatud-brandilogod] 25.08.2026
   Codex kirjutas selle 25.08 10:16 ule. Pohjus, miks need reeglid vaja on:
   baasis on a.blogo 8px paddingi ja halli taustaga, pilt object-fit:contain,
   mis jattis logo umber raami ja labipaistva PNG alla halli. Harli soovis, et
   logo taidaks kogu ristkuliku ja taust oleks koigil valge. */
.fbrand a.blogo{padding:0!important;background:#fff!important;overflow:hidden!important;}
.fbrand a.blogo img{width:100%!important;height:100%!important;object-fit:cover!important;object-position:center!important;background:#fff!important;}
.blogo{height:5rem!important;}
/* [taastatud-brandilogod] lopp */


/* [taastatud-komponendid] 25.08.2026 - Codex kirjutas need 10:16 ule.
   Burgerimenuu overlay ise elab base.css-is ja jai terveks; siin on ainult
   see, mis oli theme.css-is. */

/* --- Menuu akordion. header.php annab depth=0, .sub-menu on olemas.
       Kokkuklapp max-heightiga, sest korgus ei ole ette teada. --- */
.menu-list li.menu-item-has-children{position:relative;}
.menu-sub-toggle{position:absolute;right:0;top:.25em;width:2.75rem;height:2.75rem;
  padding:0;border:0;background:transparent;color:inherit;cursor:pointer;z-index:2;}
.menu-sub-toggle::before,.menu-sub-toggle::after{content:"";position:absolute;
  left:50%;top:50%;background:currentColor;transform:translate(-50%,-50%);}
.menu-sub-toggle::before{width:1.1rem;height:2px;}
.menu-sub-toggle::after{width:2px;height:1.1rem;}
.menu-list li.sub-open>.menu-sub-toggle::after{opacity:0;}
.menu-list .sub-menu{max-height:0;overflow:hidden;margin:0;padding:0;list-style:none;
  transition:max-height .3s ease;}
.menu-list li.sub-open>.sub-menu{max-height:32rem;}
.menu-list .sub-menu a{font-size:.85em;opacity:.8;}

/* --- Kategooriakiibid nuppudena. Baasis oli align-items:baseline, mis
       joondas ikooni teksti alusjoone jargi - sellest tuli see, et kiibid
       ei olnud reas. --- */
nav.shop-subcats{justify-content:space-between;align-items:stretch;}
nav.shop-subcats a.subcat{align-items:center!important;gap:.55rem;
  padding:.7rem 1.1rem;line-height:1.1;
  box-shadow:0 1px 2px rgba(0,0,0,.06);}
nav.shop-subcats a.subcat svg{width:1.5rem;height:1.5rem;flex:0 0 auto;}
nav.shop-subcats a.subcat:hover{border-color:#111;box-shadow:0 2px 6px rgba(0,0,0,.12);}
nav.shop-subcats a.subcat:active{transform:translateY(1px);}

/* --- Telefonis filtrid vasakult avaneva paneeli taha. --- */
@media (max-width:640px){
  .fbar{display:flex;justify-content:flex-start;margin:0 0 1rem;}
  .fbar-btn{display:inline-flex;align-items:center;gap:.5rem;
    padding:.7rem 1.2rem;border:1px solid #111;border-radius:999px;
    background:#fff;font-size:.9rem;cursor:pointer;}
  .fpanel{position:fixed;inset:0;z-index:80;background:rgba(0,0,0,.4);
    visibility:hidden;opacity:0;}
  .fpanel.open{visibility:visible;opacity:1;}
  .fpanel-inner{position:absolute;left:0;top:0;bottom:0;width:86%;max-width:22rem;
    background:#fff;overflow-y:auto;padding:3.5rem 1.25rem 2rem;
    transform:translateX(-100%);transition:transform .28s ease;}
  .fpanel.open .fpanel-inner{transform:translateX(0);}
  .fpanel-close{position:absolute;right:.75rem;top:.75rem;width:2.5rem;height:2.5rem;
    border:0;background:transparent;cursor:pointer;}
  .fpanel-close::before,.fpanel-close::after{content:"";position:absolute;
    left:50%;top:50%;width:1.2rem;height:2px;background:#111;}
  .fpanel-close::before{transform:translate(-50%,-50%) rotate(45deg);}
  .fpanel-close::after{transform:translate(-50%,-50%) rotate(-45deg);}
  html.fpanel-lock,html.fpanel-lock body{overflow:hidden;}
  .fpanel nav.shop-subcats{flex-direction:column;align-items:stretch;}
  .fpanel nav.shop-subcats a.subcat{justify-content:flex-start;}
}

/* --- Telefonis on pais fixed, et see ei lukkaks sisu korvale.
       Uleminekuanimatsiooni EI ole: taustavahelehel kulmub CSS transition
       keskele ja arvutatud vaartus loetakse kui oklab(0 0 0 / 0). --- */
@media (max-width:900px){
  #head{position:fixed;top:0;left:0;right:0;z-index:60;}
  body:not(.home) #head{background:transparent;}
  body:not(.home) #head.solid{background:#fff;box-shadow:0 1px 0 rgba(0,0,0,.08);}
}
/* [taastatud-komponendid] lopp */


/* ---- Kataloog hero: sliding represented-brand logos (Harli, C.3) ---- */

/*
 * Same technique as the homepage's partner-logo marquee (home.css .marquee /
 * .marquee-track): a doubled logo list scrolls left on a 0%->-50% loop, and a
 * mask-image fades both edges instead of a hard clip. Kept as its own component
 * here (not shared with home.css) because home.css is only enqueued on the front
 * page. The logo files themselves are white/transparent versions of the fbrand-logos
 * originals -- see the comment above $standard_hero_brand_logos in archive-product.php.
 */
.shop-hero-brands{
	position: absolute;
	/* Starts clear of .shop-hero-in (max-width 32rem) plus a gap, so the row sits
	   beside the text column instead of running underneath it (Harli, C.3 round 4). */
	left: calc(var(--edge) + 35rem);
	right: 0;
	bottom: 0;
	z-index: 1;
	overflow: hidden;
	padding: 0 var(--edge) clamp(1.2rem, 2vw, 1.8rem) 0;
	/* This strip sits over the lighter right-hand part of the hero photo, past where
	   .shop-hero-shade's diagonal darkening has already faded out -- without its own
	   backdrop the white logos lose contrast against the photo. Same base tone as the
	   shade. Masked together with the logos below, so it fades in/out with them. */
	background: linear-gradient(90deg, transparent, oklch(0.16 0.05 264 / .55) 30%, oklch(0.16 0.05 264 / .55) 100%);
	/* Wider left fade than before: with the container now narrower, logos should
	   dissolve well before reaching this edge, not appear right at it. */
	mask-image: linear-gradient(90deg, transparent, #000 22%, #000 90%, transparent);
}
.shop-hero-brands-track{
	display: flex;
	align-items: center;
	gap: clamp(2.6rem, 1.5rem + 3vw, 5.5rem);
	width: max-content;
	animation: standard-hero-brands-marq 70s linear infinite;
}
.shop-hero-brands-track img{
	height: clamp(2rem, 1.5rem + 1.6vw, 3rem);
	width: auto;
	flex: 0 0 auto;
	object-fit: contain;
	opacity: .82;
}
.shop-hero:hover .shop-hero-brands-track{
	animation-play-state: paused;
}
@keyframes standard-hero-brands-marq{
	0%{ transform: translateX(0); }
	100%{ transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce){
	.shop-hero-brands-track{
		animation: none;
	}
}

/*
 * On mobile .shop-hero switches to align-items:flex-end (see pages.css), so the
 * text block itself sits flush with the hero's bottom edge -- there is no longer
 * a safe strip below it for this row without overlapping the CTA. Hidden below
 * 700px rather than reflowed into normal flow; revisit if Harli wants it on mobile too.
 */
@media (max-width: 700px){
	.shop-hero-brands{
		display: none;
	}
}
