/* Public site — clean, modern, minimal. */

*, *::before, *::after { box-sizing: border-box; }

/* Always render the vertical scrollbar (`overflow-y: scroll`) so the layout
   never shifts left/right between pages of different heights. The scrollbar
   is styled with a clearly visible slate thumb on a transparent track so the
   gutter blends with the page background instead of looking like a white strip. */
html {
  overflow-y: scroll;
  scrollbar-width: thin;
  /* Sticky navbar is 64px tall; reserve a bit more so the scrolled-to
     section's heading isn't hidden under the bar. Matches the
     prototype's `scroll-padding-top: 4.5rem`. */
  scroll-padding-top: 4.5rem;
  /* `scroll-behavior: smooth` REMOVED — the JS smooth-anchor handler in
     pages/base.html drives the animation, and a CSS-level smooth rule
     was being applied to every per-frame `scrollTo()` the JS made,
     turning each frame into its own ~300ms browser tween that the
     next frame interrupted. Net visual was a hard jump, no glide. */
}
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--color-fg-muted);
  border-radius: 5px;
  border: 2px solid var(--color-bg);                    /* padding so thumb looks ~6px */
  background-clip: padding-box;
}
::-webkit-scrollbar-thumb:hover { background: var(--color-fg); }

html, body {
  margin: 0;
  padding: 0;
  background: var(--color-bg);
  color: var(--color-fg);
  /* Ubuntu loaded from Google Fonts in pages/base.html. System fallbacks
     run while the web-font is loading so initial paint isn't blank.
     Admin keeps `--font-sans` from tokens.css unchanged. */
  font-family: "Ubuntu", var(--font-sans);
  font-size: var(--fs-base);
  line-height: var(--lh-base);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Page-height stabiliser — give the per-page article wrapper a minimum
   height so short pages ("/", "/kontaktai") render at roughly the same
   overall vertical size as long pages ("/apie-mus"), eliminating the
   vertical drift when navigating between them. The min-height lives on
   the article (not on <main>) so any extra empty space sits ABOVE the
   contact section, not between the contact section and the footer —
   keeps the footer hugging the contact card instead of floating far
   below it. */
.page-article {
  min-height: 40vh;
}

a {
  color: var(--color-primary);
  text-decoration: none;
  transition: color var(--transition);
}
a:hover { color: var(--color-primary-hover); }
a:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; border-radius: 2px; }

img { max-width: 100%; height: auto; display: block; }

.container {
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 var(--sp-6);
}

h1, h2, h3, h4 {
  margin: 0 0 var(--sp-4);
  font-weight: 700;
  letter-spacing: -0.015em;
  color: var(--color-fg);
  line-height: var(--lh-tight);
}
h1 { font-size: clamp(var(--fs-2xl), 4vw, var(--fs-3xl)); }
h2 { font-size: var(--fs-xl); }
h3 { font-size: var(--fs-lg); }
p { margin: 0 0 var(--sp-4); color: var(--color-fg-muted); }
p:last-child { margin-bottom: 0; }

/* ----- buttons ----- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  padding: 10px 18px;
  font-size: var(--fs-sm);
  font-weight: 500;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-surface);
  color: var(--color-fg);
  cursor: pointer;
  transition: all var(--transition);
  text-decoration: none;
}
.btn:hover { background: var(--color-surface-2); border-color: var(--color-border-strong); }
.btn:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.btn.primary {
  background: var(--color-primary);
  color: var(--color-primary-fg);
  border-color: var(--color-primary);
  box-shadow: var(--shadow-sm);
}
.btn.primary:hover { background: var(--color-primary-hover); border-color: var(--color-primary-hover); color: var(--color-primary-fg); }

/* ----- navbar ----- */

.navbar {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(255,255,255,.85);
  backdrop-filter: saturate(180%) blur(16px);
  -webkit-backdrop-filter: saturate(180%) blur(16px);
  border-bottom: 1px solid var(--color-border);
  box-shadow: 0 4px 12px rgba(15, 23, 42, 0.04);
}
.navbar .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 64px;
}
.navbar .brand {
  font-weight: 700;
  font-size: var(--fs-md);
  letter-spacing: -0.02em;
  color: var(--color-fg);
}
/* Logo replaces the text brand when one is uploaded. The navbar is 64px tall
   (see `.navbar .container { height: 64px }` above), so we cap the image at
   40px to leave ~12px of breathing room top + bottom. Width is auto so the
   image's aspect ratio is preserved regardless of how it was re-encoded. */
.navbar .brand-logo {
  display: inline-flex;
  align-items: center;
  line-height: 0;
}
.navbar .brand-logo img {
  display: block;
  height: 40px;
  width: auto;
  max-width: 240px;
  object-fit: contain;
}
.navbar .menu {
  display: flex;
  gap: var(--sp-1);
  list-style: none;
  margin: 0;
  padding: 0;
  align-items: center;
}
.navbar .menu a {
  display: inline-block;
  padding: 8px 14px;
  border-radius: var(--radius-sm);
  color: var(--color-fg-muted);
  font-size: var(--fs-sm);
  font-weight: 500;
  transition: color var(--transition), background var(--transition);
}
.navbar .menu a:hover { color: var(--color-fg); background: var(--color-surface-2); }

/* ---- Under-construction placeholder ----
   Standalone full-viewport page; doesn't share the public site's navbar
   or footer. Just centers a card with the configured WYSIWYG message. */
.under-construction-body {
  margin: 0; min-height: 100vh;
  background: var(--bg, #eeece8);
  font-family: "Inter Tight", "Inter", system-ui, sans-serif;
  color: var(--ink, #1a1a18);
  display: flex; align-items: center; justify-content: center;
  padding: 2rem;
}
.under-construction {
  width: 100%; max-width: 760px;
}
.under-construction-card {
  background: var(--paper, #fafaf7);
  border: 1px solid var(--line, #d4d1c8);
  padding: 3rem 2.5rem;
  text-align: center;
}
.under-construction-logo {
  display: block; margin: 0 auto 1.5rem;
  height: 48px; width: auto; object-fit: contain;
}
.under-construction-brand {
  font-size: 1.25rem; font-weight: 600;
  letter-spacing: -0.01em;
  margin: 0 0 1.5rem;
  color: var(--deep, #3a342a);
}
.under-construction-h1 {
  font-size: clamp(1.75rem, 3.5vw, 2.5rem);
  line-height: 1.1; margin: 0 0 1rem;
  color: var(--deep, #3a342a);
  font-weight: 500;
}
.under-construction-fallback {
  font-size: 1.125rem;
  color: var(--muted, #6b6a64);
  margin: 0;
}
.under-construction-message { font-size: 1rem; line-height: 1.55; }
.under-construction-message > :first-child { margin-top: 0; }
.under-construction-message > :last-child { margin-bottom: 0; }
@media (max-width: 600px) {
  .under-construction-card { padding: 2rem 1.5rem; }
}

/* ---- Burger toggle (mobile only) ----------------------------------
   Hidden on desktop; visible at ≤768px. When the navbar carries
   `.is-open` (set by static/js/navbar-toggle.js), the menu drops down
   as a panel below the bar, and the burger icon swaps for a close X.
*/
.navbar-toggle {
  display: none;
  background: transparent;
  border: 0;
  padding: 8px;
  margin: 0;
  cursor: pointer;
  color: var(--color-fg);
  border-radius: var(--radius-sm);
  transition: background 120ms ease;
}
.navbar-toggle:hover { background: var(--color-surface-2); }
.navbar-toggle-icon,
.navbar-toggle-icon-close { width: 24px; height: 24px; display: block; }
.navbar-toggle-icon-close { display: none; }

@media (max-width: 768px) {
  .navbar-toggle { display: inline-flex; align-items: center; justify-content: center; }
  .navbar .menu {
    /* Drop-down panel pinned under the 64px navbar. Flex column so the
       items stack; full container width with comfortable tap targets. */
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    gap: 0;
    padding: 0.5rem 0;
    background: var(--paper);
    border-bottom: 1px solid var(--line);
    box-shadow: 0 12px 24px -16px rgba(0, 0, 0, 0.18);
  }
  .navbar.is-open .menu { display: flex; }
  .navbar .menu li { width: 100%; }
  .navbar .menu li.cta {
    /* CTA item gets a soft separator so it reads as the call-to-action. */
    margin-top: 0.25rem;
    border-top: 1px solid var(--line);
  }
  .navbar .menu a {
    display: block;
    padding: 14px 24px;
    border-radius: 0;
    font-size: 1rem;
  }
  /* Burger ↔ X icon swap when the menu is open. */
  .navbar.is-open .navbar-toggle-icon { display: none; }
  .navbar.is-open .navbar-toggle-icon-close { display: block; }
  /* The public-side `body:not(.admin) .navbar .menu a` rule above zeroes
     the horizontal padding (it's the right look for the desktop inline
     bar but glues each item to the screen edge in the drop-down). Win
     specificity by matching the same `body:not(.admin)` prefix here. */
  body:not(.admin) .navbar .menu a {
    padding: 16px var(--sp-6);
    font-size: 0.9375rem;
  }
}
.navbar .menu li.cta a {
  background: var(--color-primary);
  color: var(--color-primary-fg);
  padding: 8px 18px;
}
.navbar .menu li.cta a:hover { background: var(--color-primary-hover); }

/* `.hero` was the previous home-page wrapper; home.html now uses the same
   `<article class="page-article">` shell as the rest of the static pages
   (so visiting "/" looks structurally identical to "/apie-mus" etc.), and
   the `.hero` rules are no longer referenced by any template. */

/* ----- static pages (home, about-us, contact-us, /menu, any /<slug>) ----- */

.page-article {
  padding: clamp(var(--sp-10), 8vw, var(--sp-12)) 0;
}
.page-article-header {
  max-width: 720px;
  margin: 0 0 var(--sp-8);
}
.page-article-header h1 {
  margin: 0 0 var(--sp-3);
}
.page-article-lead {
  font-size: var(--fs-lg);
  color: var(--color-fg-muted);
  line-height: var(--lh-snug);
  margin: 0;
}
.page-article .page-content {
  max-width: 680px;
  font-size: var(--fs-md);
  color: var(--color-fg);
  line-height: var(--lh-base);
}
.page-article .page-content > * + * { margin-top: var(--sp-4); }
.page-article .page-content h2 {
  font-size: var(--fs-xl);
  margin-top: var(--sp-8);
  margin-bottom: var(--sp-3);
}
.page-article .page-content h3 {
  font-size: var(--fs-lg);
  margin-top: var(--sp-6);
  margin-bottom: var(--sp-2);
}
.page-article .page-content p { color: var(--color-fg-muted); margin: 0; }
.page-article .page-content p strong { color: var(--color-fg); }
.page-article .page-content ul,
.page-article .page-content ol { padding-left: var(--sp-5); color: var(--color-fg-muted); }
.page-article .page-content li { margin: var(--sp-1) 0; }
.page-article .page-content li a { color: var(--color-primary); font-weight: 500; }
.page-article .page-content code {
  font-family: var(--font-mono);
  font-size: 0.9em;
  background: var(--color-surface-2);
  padding: 1px 6px;
  border-radius: 4px;
  border: 1px solid var(--color-border);
}
.page-article .page-content blockquote {
  margin: var(--sp-6) 0;
  padding: var(--sp-4) var(--sp-5);
  border-left: 3px solid var(--color-primary);
  background: var(--color-primary-soft);
  border-radius: 0 var(--radius) var(--radius) 0;
  color: var(--color-fg);
  font-style: italic;
}
.page-article .page-content a {
  color: var(--color-primary);
  font-weight: 500;
  border-bottom: 1px solid transparent;
  transition: border-color var(--transition);
}
.page-article .page-content a:hover { border-bottom-color: currentColor; }

/* ----- contact ----- */

.contact {
  background: linear-gradient(180deg, var(--color-bg) 0%, var(--color-surface) 100%);
  padding: clamp(var(--sp-6), 5vw, var(--sp-8)) 0;
  border-top: 1px solid var(--color-border);
}
.contact-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr);
  gap: clamp(var(--sp-6), 5vw, var(--sp-10));
  align-items: start;
}
@media (max-width: 820px) {
  .contact-grid { grid-template-columns: 1fr; gap: var(--sp-6); }
}

.contact-info h2 { margin-bottom: var(--sp-4); font-size: var(--fs-xl); }
.contact-info .lead {
  font-size: var(--fs-md);
  color: var(--color-fg-muted);
  margin-bottom: var(--sp-6);
  line-height: var(--lh-snug);
  max-width: 460px;
}

.contact-details {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--sp-4);
}
.contact-details li {
  display: grid;
  grid-template-columns: 80px 1fr;
  gap: var(--sp-4);
  padding: var(--sp-3) 0;
  border-top: 1px solid var(--color-border);
  font-size: var(--fs-sm);
}
.contact-details li:last-child { padding-bottom: 0; }
.contact-details .label {
  font-size: var(--fs-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-fg-muted);
  padding-top: 2px;
}
.contact-details a { color: var(--color-fg); font-weight: 500; }
.contact-details a:hover { color: var(--color-primary); }
.contact-details .company-details { color: var(--color-fg); line-height: 1.5; }

.contact-form-wrapper { width: 100%; }

/* Honeypot — visually hidden but still in the form so bots fill it. */
.honeypot {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.contact-form {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--sp-4);
  background: var(--color-surface);
  padding: var(--sp-6);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}
.contact-form label {
  display: grid;
  gap: 0;
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--color-fg);
  position: relative;                /* anchors the required-asterisk overlay */
}
/* The email field spans the full form width (its own row) — keyed off
   the input's `type="email"` so it works regardless of what the
   ContactFormField enum value happens to be. */
.contact-form label:has(input[type="email"]) {
  grid-column: 1 / -1;
}

/* Required-field asterisk — overlaid as a real character at the input's
   right edge. `:placeholder-shown` makes it visible only while the field
   is empty, so the marker tracks the placeholder's lifecycle. Visual
   properties match the placeholder text exactly (color, size, weight) so
   the asterisk reads as part of the prompt, not a separate accent.
   Pointer-events disabled so a click on the asterisk still focuses the
   input behind it. */
.contact-form label.is-required:has(input:placeholder-shown, textarea:placeholder-shown)::after {
  content: "*";
  position: absolute;
  top: 13px;
  right: 14px;
  color: var(--color-fg-subtle);
  font-size: var(--fs-sm);
  font-weight: 400;
  line-height: 1;
  pointer-events: none;
}

/* Only the message textarea spans the full row width. EMAIL no longer
   spans full width so it can share its row with the "Tema" subject
   select (Tema sits below PHONE on wide screens). Name/phone/email/tema
   share rows via the auto-fit grid. */
.contact-form label:has(textarea),
.contact-form label[data-field="message"] { grid-column: 1 / -1; }

/* Hidden-but-accessible label — placeholder serves as the visual prompt;
   screen readers still announce the real label. */
.contact-form .sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.contact-form input,
.contact-form textarea,
.contact-form select {
  width: 100%;
  padding: 11px 14px;
  font: inherit;
  font-size: var(--fs-sm);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-input);
  background: var(--color-surface);
  color: var(--color-fg);
  transition: border-color var(--transition), box-shadow var(--transition);
}
/* Placeholder reads as the prompter — slightly dimmed so it doesn't compete
   with typed values. Cross-browser via the standard ::placeholder selector. */
.contact-form input::placeholder,
.contact-form textarea::placeholder {
  color: var(--color-fg-subtle);
  opacity: 1;                       /* Firefox defaults to 0.55, normalise it */
  font-weight: 400;
}
.contact-form input:focus, .contact-form textarea:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px var(--color-primary-soft);
}
.contact-form textarea { min-height: 120px; resize: vertical; }
.contact-form button[type=submit] { grid-column: 1 / -1; justify-self: start; }
.contact-form button[type=submit][disabled] {
  opacity: 0.55;
  cursor: not-allowed;
}
/* Submit row hosts both the button and the inline flash. The flash is
   absolutely positioned so it never contributes to the form's height —
   the form's vertical rhythm stays identical whether the message is on
   screen or not. `.contact-submit-row` is the grid cell; the message
   floats inside it next to the button. */
.contact-form .contact-submit-row {
  grid-column: 1 / -1;
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  min-height: 0;
}
.contact-form .err {
  grid-column: 1 / -1;
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--radius);
  font-size: var(--fs-sm);
  background: var(--color-danger-soft);
  color: var(--color-danger);
}
/* Success flash: shown inline next to the submit button, no impact on
   form height. Fade is driven by adding `.is-leaving` from JS at the
   15s mark — the transition runs and the element is removed after. */
.contact-form .flash-ok {
  display: inline-flex;
  align-items: center;
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--radius);
  font-size: var(--fs-sm);
  background: var(--color-success-soft);
  color: var(--color-success);
  font-weight: 500;
  opacity: 1;
  transition: opacity 600ms ease;
  pointer-events: none;
}
.contact-form .flash-ok.is-leaving { opacity: 0; }
/* Error flash — same shape as `.flash-ok`, swapped to the danger
   palette. Shown by `static/js/contact-form-flash.js` when the AJAX
   submit hits a validation / rate-limit / CSRF rejection from
   `_contact_redirect(..., error=…)`. */
.contact-form .flash-err {
  display: inline-flex;
  align-items: center;
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--radius);
  font-size: var(--fs-sm);
  background: var(--color-danger-soft, #fdecec);
  color: var(--color-danger, #b3261e);
  font-weight: 500;
  opacity: 1;
  transition: opacity 600ms ease;
  pointer-events: none;
}
.contact-form .flash-err.is-leaving { opacity: 0; }

/* ----- footer ----- */

.site-footer {
  background: var(--color-sidebar-bg);
  color: var(--color-sidebar-fg);
  /* Top padding used to be `--sp-12` (64px) because there was a column block
     of company details / phone / email above the footer-pages strip. That
     block was removed, leaving only the page-link strip + optional copyright
     line, so the large top padding produced a sea of dead space. Trimmed to
     `--sp-6` (24px) — still gives a visual gap from the page content above. */
  padding: var(--sp-6) 0;
  /* Was `var(--sp-16)` (96 px) — tuned for the old hero-style landing
     page that had a much bigger visual rhythm. The current `.page-article`
     layout sits much tighter, so a smaller buffer reads as intentional
     spacing instead of "the footer floated away from the content". */
  margin-top: var(--sp-6);
}
.site-footer a { color: var(--color-sidebar-fg); }
.site-footer a:hover { color: #fff; }
.site-footer .row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--sp-8);
  margin-bottom: var(--sp-10);
}
.site-footer h4 {
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-sidebar-fg-muted);
  margin-bottom: var(--sp-3);
}
.site-footer ul { list-style: none; padding: 0; margin: 0; display: grid; gap: 6px; font-size: var(--fs-sm); }
/* Inline strip of admin-flagged footer pages — single row of links separated
   by a thin divider; wraps gracefully on narrow viewports. Previously had a
   top border + margin/padding to separate it from a now-removed column block
   above; those are gone so the strip sits flush at the top of the footer. */
.site-footer .footer-pages {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2) var(--sp-4);
  align-items: center;
  font-size: var(--fs-sm);
}
.site-footer .footer-pages li {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  color: var(--color-sidebar-fg-muted);
}
/* Vertical divider after each link except the last. */
.site-footer .footer-pages li:not(:last-child)::after {
  content: "";
  width: 1px;
  height: 12px;
  background: rgba(255, 255, 255, 0.16);
  margin-left: var(--sp-4);
}
.site-footer .footer-pages a {
  color: var(--color-sidebar-fg-muted);
  text-decoration: none;
  transition: color var(--transition);
}
.site-footer .footer-pages a:hover { color: #fff; }

/* When `.footer-pages` is present, the copyright block underneath drops its
   own top border so the two horizontal lines don't double up. */
.site-footer .footer-pages + .copyright {
  border-top: none;
  padding-top: var(--sp-3);
  margin-top: var(--sp-3);
}

.site-footer .copyright {
  border-top: 1px solid rgba(255,255,255,.08);
  padding-top: var(--sp-5);
  font-size: var(--fs-sm);
  color: var(--color-sidebar-fg-muted);
}
.site-footer .powered-by {
  margin-left: var(--sp-3);
  padding-left: var(--sp-3);
  border-left: 1px solid rgba(255,255,255,.12);
  color: var(--color-sidebar-fg-muted);
}
.site-footer .powered-by a {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: rgba(255,255,255,.25);
  text-underline-offset: 2px;
  transition: color var(--transition);
}
.site-footer .powered-by a:hover { color: #fff; text-decoration-color: currentColor; }

/* ----- error pages ----- */

/* Legacy `.error-page` — kept for any project still using the old template;
   the new error pages use `.error-hero` below. */
.error-page { padding: var(--sp-16) 0; text-align: center; }
.error-page h1 { font-size: var(--fs-3xl); margin-bottom: var(--sp-3); }
.error-page p { font-size: var(--fs-md); }
.error-page code { background: var(--color-surface-2); padding: 2px 6px; border-radius: 4px; font-size: var(--fs-sm); }

/* ----- Error hero (404 / 500) -----
   Plain background — only the big "404" / "500" badge picks up the theme
   gradient (see `.error-code` below). The hero exists to centre the
   error block at hero-like vertical padding without any tinted backdrop. */
.error-hero {
  /* Default fallback — overridden inline on /404 to follow the theme. */
  --theme-color: var(--color-primary);
  position: relative;
  padding: clamp(var(--sp-12), 12vw, var(--sp-16)) 0;
  background: var(--color-bg);
  text-align: center;
}
.error-hero-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* Big "404" graphic — gradient-filled, set in the project font at a punchy
   size. Uses background-clip:text so the colour inherits the theme color.
   Second stop is the same theme color blended toward white for a smooth
   light-end fade. */
.error-code {
  display: block;
  font-family: "Ubuntu", var(--font-sans);
  font-size: clamp(96px, 20vw, 200px);
  font-weight: 800;
  line-height: 0.9;
  letter-spacing: -0.04em;
  margin-bottom: var(--sp-4);
  background: linear-gradient(
    135deg,
    var(--theme-color, var(--color-primary)) 0%,
    color-mix(in srgb, var(--theme-color, var(--color-primary)) 45%, white) 100%
  );
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
          color: transparent;
  user-select: none;
}
/* 500 variant — warm tones to read as "warning" rather than "missing". */
.error-code-warn {
  background: linear-gradient(
    135deg,
    #f59e0b 0%,
    #ef4444 100%
  );
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
          color: transparent;
}

.error-title {
  font-size: clamp(var(--fs-2xl), 4vw, var(--fs-3xl));
  letter-spacing: -0.02em;
  margin: 0 0 var(--sp-4);
  color: var(--color-fg);
}
.error-lead {
  max-width: 560px;
  font-size: var(--fs-lg);
  color: var(--color-fg-muted);
  line-height: var(--lh-snug);
  margin: 0 0 var(--sp-6);
}
.error-path {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  flex-wrap: wrap;
  justify-content: center;
  font-size: var(--fs-sm);
  color: var(--color-fg-muted);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: var(--sp-2) var(--sp-4);
  margin: 0 auto var(--sp-6);
  max-width: 100%;
  word-break: break-all;
}
.error-path-label {
  font-weight: 600;
  color: var(--color-fg);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-size: var(--fs-xs);
}
.error-path code {
  background: transparent;
  padding: 0;
  border: 0;
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  color: var(--color-primary);
}

.error-actions {
  display: flex;
  gap: var(--sp-3);
  flex-wrap: wrap;
  justify-content: center;
}
.error-actions .btn svg { width: 16px; height: 16px; }

/* ===========================================================================
   betonas — public site styling for Slice 2-5 class hooks.
   Reads tokens from `body:not(.admin)` scope in tokens.css.
   =========================================================================== */

/* ---- Top bar (overrides for the public/betonas theme) ----
   The shared `.navbar` rules above default to a white frosted bar so the
   FastAPI template ships looking decent before any branding. On the
   betonas public site we want the bar to blend with the page background
   (matching the prototype's translucent sand-toned topbar) and use the
   uppercase tracked label style for links. Scoped to body:not(.admin)
   so the admin's white-on-slate topbar is untouched. */
body:not(.admin) .navbar {
  background: rgba(238, 236, 232, 0.92);                   /* same color as --bg */
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
  box-shadow: 0 4px 12px -6px rgba(58, 52, 42, 0.18);
}
/* Widen the navbar's inner container to match the prototype's
   `max-w-[1400px] px-6 lg:px-12` and the hero's own widened container. */
body:not(.admin) .navbar .container {
  max-width: 1400px;
  padding-left: var(--sp-6); padding-right: var(--sp-6);
}
@media (min-width: 1024px) {
  body:not(.admin) .navbar .container {
    padding-left: 3rem; padding-right: 3rem;
  }
}
body:not(.admin) .navbar .menu { gap: var(--sp-8); }
body:not(.admin) .navbar .menu a {
  /* Prototype's `.label` type style — uppercase, tracked, small. */
  font-family: "Inter Tight", "Inter", system-ui, sans-serif;
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  font-weight: 500;
  color: var(--ink);
  background: transparent;
  border-radius: 0;
  padding: 8px 0;
}
body:not(.admin) .navbar .menu a:hover {
  color: var(--blue);
  background: transparent;
}
body:not(.admin) .navbar .menu li.cta a {
  /* CTA still stands out, but in the betonas palette (deep ink button). */
  background: var(--deep);
  color: var(--paper);
  padding: 10px 18px;
}
body:not(.admin) .navbar .menu li.cta a:hover { background: var(--blue); }


/* Type primitives — mirror the prototype's display / label / muted classes. */
.label {
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--blue);
  font-weight: 500;
  margin: 0;
}
.muted { color: var(--muted); }
.num { font-variant-numeric: tabular-nums; }

/* ---- Hero ---- */
/* Sizing follows the prototype's `py-16 md:py-24` (4-6rem vertical) + a
   7/5 grid that lets the text column drive overall height, while the
   image column stretches to fill that same height (min-height 520px).
   Title type bumps to clamp(3.5rem, 8vw, 8rem) — the prototype renders
   ~8vw on md+ which on a 1400px container reaches ~7rem. The whole
   block now uses the wider 1400px container width like the prototype. */
.hero {
  padding: 4rem 0;
  background: linear-gradient(180deg, var(--bg) 0%, var(--ice-soft) 100%);
  border-bottom: 1px solid var(--line);
}
@media (min-width: 768px) { .hero { padding: 6rem 0; } }
.hero > .container {
  max-width: 1400px;
  padding-left: var(--sp-6); padding-right: var(--sp-6);
}
@media (min-width: 1024px) {
  .hero > .container { padding-left: 3rem; padding-right: 3rem; }
}
.hero-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 2.5rem;
  align-items: stretch;
}
/* Two-column 7/5 split kicks in at md (768px) to match the prototype's
   `md:grid-cols-12` + `md:col-span-7/5`. Earlier breakpoint at 900px
   left a 768–900px gap where the prototype was two-column but we were
   stacked. */
@media (min-width: 768px) {
  .hero-grid { grid-template-columns: 7fr 5fr; }
}
.hero-text { display: flex; flex-direction: column; }
.hero-eyebrow {
  font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--blue); margin: 0 0 1.5rem;
  font-weight: 500;
}
.hero-title {
  font-family: "Inter Tight", "Inter", system-ui, sans-serif;
  font-weight: 500; line-height: 0.96; letter-spacing: -0.025em;
  color: var(--deep);
  /* Mirror the prototype's `text-[14vw] md:text-[8vw]` literally — no
     upper cap. The cap was making the title smaller than the prototype
     on wide viewports, which collapsed the hero's vertical rhythm: the
     text column drives row height, and a shorter text column drags the
     stretched image column down with it. */
  font-size: 14vw;
  margin: 0;
}
@media (min-width: 768px) {
  .hero-title { font-size: 8vw; }
}
.hero-accent { color: var(--blue); }
.hero-slogan {
  /* Prototype: `text-2xl md:text-3xl` — discrete 1.5→1.875rem step. */
  font-size: 1.5rem;
  color: var(--muted);
  margin-top: 2rem; max-width: 42rem; line-height: 1.3;
}
@media (min-width: 768px) {
  .hero-slogan { font-size: 1.875rem; }
}
.hero-ctas { margin-top: auto; padding-top: 2.5rem; display: flex; gap: 1rem; flex-wrap: wrap; }
.hero-cta {
  display: inline-block; padding: 12px 24px;
  border: 1px solid var(--deep); color: var(--deep); background: transparent;
  font-size: 0.875rem; font-weight: 500; letter-spacing: 0.04em;
  text-decoration: none; transition: all var(--transition);
}
.hero-cta:hover { background: var(--deep); color: var(--paper); }
.hero-cta-accent { background: var(--deep); color: var(--paper); }
.hero-cta-accent:hover { background: var(--blue); border-color: var(--blue); }
.hero-slider {
  /* `margin: 0` overrides the browser's default `<figure>` margin
     (1em 40px) — without it, the image sits 40px inside the grid cell's
     right edge and no longer lines up with the rightmost letter of the
     rightmost top-menu item. The navbar and the hero already share
     identical container constraints (max-width 1400px, same horizontal
     padding), so resetting figure margin is what completes the line-up. */
  margin: 0;
  position: relative; min-height: 520px; display: flex; flex-direction: column;
}
.hero-slider .hero-slide { display: block; flex: 1; }
.hero-slider .hero-slide img {
  width: 100%; height: 100%; min-height: 520px; object-fit: cover;
  filter: brightness(1.0) saturate(0.78) contrast(1.02);
}
.hero-caption {
  margin-top: var(--sp-3);
  font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--blue);
}

/* ---- Composer / content areas ---- */
/* Prototype uses `py-24` (6rem) section padding, mb-12/mb-16 between
   header and grid, and a wider `max-w-[1300px]` container — bump the
   composer's own container to match so the content rhythm reads the
   same as the prototype. */
.composer-area { padding: 6rem 0; border-bottom: 1px solid var(--line); }
.composer-area:nth-of-type(even) { background: var(--paper); }
.composer-area > .container { max-width: 1300px; }
.composer-area-header { text-align: center; margin-bottom: 4rem; }
/* Mobile: the base `6rem 0` section padding and `4rem` header margin
   read as great whitespace on desktop but feel excessive on small
   screens, where the user mostly wants to keep scrolling between
   sections. Cap both for narrow viewports. */
@media (max-width: 768px) {
  .composer-area { padding: 2.5rem 0; }
  .composer-area-header { margin-bottom: 1.5rem; }
}
.composer-area-header h2 {
  font-family: "Inter Tight", "Inter", system-ui, sans-serif; font-weight: 500;
  line-height: 0.96; letter-spacing: -0.025em; color: var(--deep);
  font-size: clamp(2.5rem, 6vw, 4.5rem);
  margin: var(--sp-3) 0 var(--sp-4);
}
/* Subtitle below the section H2 — prototype uses `text-lg muted text-center
   max-w-2xl mx-auto mb-12`, e.g. the "Ta pati erdvė..." line under
   Įrengimas. The composer header centres the H2 already, so we only have
   to give the paragraph the right type and width here. */
.composer-area-header p.muted {
  font-size: 1.125rem;
  line-height: 1.5;
  color: var(--muted);
  max-width: 42rem;
  margin: 0 auto;
}
.composer-grid { display: grid; gap: 2rem; }
.composer-grid-2 { grid-template-columns: repeat(2, 1fr); }
.composer-grid-3 { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 768px) {
  .composer-grid-2, .composer-grid-3 { grid-template-columns: 1fr; }
}

/* ---- Ongoing-projects ("Vykdomi projektai") count-driven grid ----
   A flexbox (not the fixed grid above) so 1-6 projects always fill the
   row comfortably and the last row centers any orphans. Tiles cap at a
   third of the row; flex-grow makes 1-3 stretch to fill the width.
   data-count overrides give the exact "clean row" widths:
     1→full · 2→halves · 4→2×2 ; 3/5/6 fall through to the 3-up default
     (5 leaves 2 centered on the second row, 6 is 3×3=two rows). */
.composer-ongoing-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 2rem;
  justify-content: center;
}
/* Width rules target any direct child (`> *`) so the same count-driven
   layout works whether the tile is `.composer-tile` (homepage) or
   `.tile-card` (portfolio page). Inner overrides further down stay
   scoped to a specific child class where they need to dig into
   tile-internal markup. */
.composer-ongoing-grid > * {
  flex: 1 1 280px;
  max-width: calc((100% - 4rem) / 3);   /* 3 across, minus 2 gaps */
}
.composer-ongoing-grid[data-count="1"] > * {
  flex-basis: 100%;
  max-width: 100%;
}
.composer-ongoing-grid[data-count="2"] > *,
.composer-ongoing-grid[data-count="4"] > * {
  flex-basis: calc((100% - 2rem) / 2);  /* 2 across, minus 1 gap */
  max-width: calc((100% - 2rem) / 2);
}
@media (max-width: 768px) {
  .composer-ongoing-grid > *,
  .composer-ongoing-grid[data-count="2"] > *,
  .composer-ongoing-grid[data-count="4"] > * {
    flex-basis: 100%;
    max-width: 100%;
  }
}
/* Single ongoing project on tablet/desktop: a full-width portrait/
   landscape image is far too tall, so lay the project details to the
   RIGHT of the image (2-col) instead of stacked below it, and cap the
   image height. Mobile (≤768px) keeps the stacked card. Works for both
   `.composer-tile` and `.tile-card` since both have an `<img>` and a
   sibling body div as their direct children. */
@media (min-width: 769px) {
  .composer-ongoing-grid[data-count="1"] > * {
    display: grid;
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
    gap: var(--sp-6);
    align-items: center;
  }
  .composer-ongoing-grid[data-count="1"] > * > img {
    max-height: 600px;
  }
  .composer-ongoing-grid[data-count="1"] > .composer-tile .composer-tile-body {
    padding-top: 0;   /* sits beside the image, not below it */
  }
  .composer-ongoing-grid[data-count="1"] > .tile-card .tile-card-body {
    padding-top: 0;
  }
  /* Scale the portfolio-page `.tile-card` typography up for the
     single-project case so the side-by-side body doesn't look
     undersized next to the much larger image. Mirrors the homepage's
     single-tile treatment for `.composer-tile`. */
  .composer-ongoing-grid[data-count="1"] > .tile-card .tile-card-meta-row {
    margin-top: 0;
  }
  .composer-ongoing-grid[data-count="1"] > .tile-card .tile-card-meta-row .label {
    font-size: 0.9375rem;
    letter-spacing: 0.14em;
  }
  .composer-ongoing-grid[data-count="1"] > .tile-card .tile-card-badge {
    font-size: 0.875rem;
    padding: 5px 14px;
  }
  .composer-ongoing-grid[data-count="1"] > .tile-card .tile-card-name {
    font-size: clamp(2.25rem, 4vw, 3.5rem);
    line-height: 1.05;
    margin-top: 0.75rem;
  }
  .composer-ongoing-grid[data-count="1"] > .tile-card .tile-card-slogan {
    font-size: 1.125rem;
    line-height: 1.5;
    margin-top: 0.75rem;
  }
  .composer-ongoing-grid[data-count="1"] > .tile-card .tile-card-stats {
    margin-top: 1.75rem;
    padding-top: 1.5rem;
    gap: 6px 16px;
  }
  .composer-ongoing-grid[data-count="1"] > .tile-card .tile-card-stats dt {
    font-size: 0.9375rem;
  }
  .composer-ongoing-grid[data-count="1"] > .tile-card .tile-card-stats dd {
    font-size: 1.25rem;
  }
  /* Scale the body typography up so it doesn't look undersized next to
     the much larger side-by-side image. Fluid sizes keep it sensible
     from 769px up to wide desktops. */
  .composer-ongoing-grid[data-count="1"] > .composer-tile .composer-tile-name {
    font-size: clamp(2.75rem, 4.5vw, 4rem);
    line-height: 1.05;
  }
  .composer-ongoing-grid[data-count="1"] > .composer-tile .composer-tile-slogan {
    font-size: 1.125rem;
    line-height: 1.5;
    margin-top: 0.75rem;
  }
  .composer-ongoing-grid[data-count="1"] > .composer-tile .composer-tile-index {
    font-size: 0.9375rem;
    letter-spacing: 0.12em;
  }
  .composer-ongoing-grid[data-count="1"] > .composer-tile .composer-tile-meta {
    font-size: 1.25rem;
    margin-top: 1.75rem;
    padding-top: 1.5rem;
  }
}

/* ---- Portfolio tiles ---- */
.composer-tile, .portfolio-tile {
  display: block; background: var(--paper); border: 1px solid var(--line);
  padding: var(--sp-5); text-decoration: none; color: inherit;
  transition: all var(--transition);
}
.composer-tile:hover, .portfolio-tile:hover {
  background: var(--ice-tint); border-color: var(--blue);
  box-shadow: 0 6px 18px -10px rgba(58, 52, 42, 0.25);
}
/* Default thumbnail aspect — completed-portfolio + listing pages use the
   classic 4:3 landscape crop. */
.composer-tile img, .portfolio-tile-img {
  width: 100%; aspect-ratio: 4/3; object-fit: cover;
  filter: brightness(1.0) saturate(0.78) contrast(1.02); display: block;
}
/* Ongoing-projects content area — tall portrait crop (4:5) to match the
   prototype's vykdomi-card layout. Scoped to .composer-ongoing so only
   the ongoing grid uses this shape — completed-portfolio and listing
   pages stay landscape. */
.composer-ongoing .composer-tile img { aspect-ratio: 4/5; }

/* ---- Completed-projects tile ----
   Prototype-matching: image + text side-by-side in a 2-col grid,
   NO card chrome (no border, no padding, no surface). The whole
   anchor is the hover/focus target — h3 shifts color on hover. */
.composer-completed .composer-grid { gap: 2rem; }
.completed-tile {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.5rem;
  align-items: center;
  background: transparent;
  border: 0;
  padding: 0;
  text-decoration: none;
  color: inherit;
}
.completed-tile-img {
  width: 100%;
  aspect-ratio: 4/3;
  object-fit: cover;
  filter: brightness(1.0) saturate(0.78) contrast(1.02);
  display: block;
}
.completed-tile-body { padding-top: 0; }
.completed-tile-name {
  font-family: "Inter Tight", "Inter", system-ui, sans-serif;
  font-weight: 500;
  font-size: 1.875rem;
  line-height: 1.1;
  color: var(--deep);
  margin: 0.5rem 0 0;
  transition: color var(--transition);
}
.completed-tile:hover .completed-tile-name { color: var(--blue); }
.completed-tile-slogan {
  font-size: 1rem;
  color: var(--muted);
  margin: 0.5rem 0 0;
  line-height: 1.4;
}
.completed-tile-meta {
  font-size: 0.875rem;
  color: var(--muted);
  margin: 1rem 0 0;
}
@media (max-width: 700px) {
  .completed-tile { grid-template-columns: 1fr; }
}
.portfolio-tile-img-placeholder { background: var(--ice-soft); }
.composer-tile-body, .portfolio-tile-body { padding-top: var(--sp-4); }
.composer-tile-body h3, .portfolio-tile-name,
.composer-tile-body .composer-tile-name {
  font-family: "Inter Tight", "Inter", system-ui, sans-serif; font-weight: 500;
  font-size: 1.875rem; line-height: 1.1; color: var(--deep);
  margin: 0.5rem 0 0;
}
/* Slogan style — matches prototype `text-base muted`. Was incorrectly
   styled with the all-caps `.label` glyph; the new explicit class
   keeps it as a normal sentence. */
.composer-tile-slogan {
  font-size: 1rem;
  color: var(--muted);
  margin: 0.5rem 0 0;
  line-height: 1.4;
}
.composer-tile-index { margin: 1.25rem 0 0; }

/* Meta grid: matches prototype `grid-cols-2 gap-y-1 text-sm border-t pt-4 num`.
   Each row is a label (muted, left-aligned) + value (right-aligned). */
.composer-tile-meta {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 4px 12px;
  border-top: 1px solid var(--line);
  padding-top: var(--sp-4);
  margin-top: 1.25rem;
  font-size: 0.875rem;
  font-variant-numeric: tabular-nums;
}
.composer-tile-meta > div { display: contents; }
.composer-tile-meta dt { color: var(--muted); margin: 0; }
.composer-tile-meta dd {
  margin: 0;
  text-align: right;
  color: var(--ink);
}
/* Portfolio listing page keeps the old 3-col compact look — that page
   has its own card chrome so the meta block can stay denser. */
.portfolio-tile-meta {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px 12px;
  border-top: 1px solid var(--line); padding-top: var(--sp-3);
  margin-top: var(--sp-4); font-size: 0.875rem;
}
.portfolio-tile-meta dt { color: var(--muted); font-size: 0.75rem; }
.portfolio-tile-meta dd { margin: 0; font-variant-numeric: tabular-nums; }

/* ---- Portfolio listing page — prototype-matching layout ----
   Each major block is a full-width `<section>` with its own border
   spanning the viewport. The header section carries the betonas
   `--bg → --ice-soft` gradient; the completed section sits on
   `--paper`; "ongoing" inherits the page bg. 1300px container
   (matches the prototype's `max-w-[1300px]`) with px-6 lg:px-12. */
.portfolio-page { padding: 0; }
.portfolio-section { border-bottom: 1px solid var(--line); }
.portfolio-page-container {
  /* Aligned to the topbar's `max-width: 1400px` + `padding: var(--sp-6)` /
     `3rem` at lg, so the portfolio content's left/right boundaries sit
     on the same vertical lines as the logo (left) and the rightmost
     letter of the rightmost menu item (right). */
  max-width: 1400px;
  margin: 0 auto;
  padding: 0 var(--sp-6);
  box-sizing: border-box;
}
@media (min-width: 1024px) {
  .portfolio-page-container { padding: 0 3rem; }
}

.portfolio-section-header > .portfolio-page-container,
.portfolio-section > .portfolio-page-container {
  padding-top: 5rem;
  padding-bottom: 5rem;
}
@media (max-width: 768px) {
  .portfolio-section-header > .portfolio-page-container,
  .portfolio-section > .portfolio-page-container {
    padding-top: 4rem;
    padding-bottom: 4rem;
  }
}

.portfolio-section-header {
  background: linear-gradient(180deg, var(--bg) 0%, var(--ice-soft) 100%);
}
.portfolio-section-completed { background: var(--paper); }

.portfolio-h1 {
  font-family: "Inter Tight", "Inter", system-ui, sans-serif;
  font-weight: 500;
  line-height: 0.96;
  letter-spacing: -0.025em;
  color: var(--deep);
  font-size: clamp(2.5rem, 6vw, 4.5rem);
  margin: 0.75rem 0 0;
}
.portfolio-intro {
  font-size: 1.25rem;
  color: var(--muted);
  margin: 1.5rem 0 0;
  max-width: 42rem;
  line-height: 1.45;
}

/* Section title row — label+title block on the left, count on the right.
   Distinct class from `.portfolio-section-header` (which is the outer
   gradient section wrapper) to avoid selector clashes. */
.portfolio-section-title-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin: 0 0 2.5rem;
}
.portfolio-h2 {
  font-family: "Inter Tight", "Inter", system-ui, sans-serif;
  font-weight: 500;
  line-height: 0.96;
  letter-spacing: -0.025em;
  color: var(--deep);
  font-size: clamp(2rem, 4.5vw, 3rem);
  margin: 0.5rem 0 0;
}
.portfolio-count {
  color: var(--muted);
  font-size: 0.875rem;
  margin: 0;
}
@media (max-width: 700px) {
  .portfolio-count { display: none; }
}

/* Grid — 3 cols on lg, 2 on md, 1 on small. Matches prototype `gap-7`. */
.portfolio-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.75rem;
}
@media (max-width: 900px) { .portfolio-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 600px) { .portfolio-grid { grid-template-columns: 1fr; } }

/* ---- Tile card (shared with the prototype's `.tile-card`) ---- */
.tile-card {
  display: block;
  background: var(--paper);
  border: 1px solid var(--line);
  padding: 1.25rem;
  color: inherit;
  text-decoration: none;
  transition: background 180ms ease, border-color 180ms ease, box-shadow 180ms ease;
}
.tile-card:hover,
.tile-card:focus-visible {
  background: var(--ice-tint);
  border-color: var(--blue);
  box-shadow: 0 6px 18px -10px rgba(58, 52, 42, 0.25);
  outline: none;
}
.tile-card:hover .tile-card-name { color: var(--blue); }
.tile-card-img {
  width: 100%;
  aspect-ratio: 4/3;
  object-fit: cover;
  filter: brightness(1.0) saturate(0.78) contrast(1.02);
  display: block;
}
.tile-card-img-placeholder { background: var(--ice-soft); }
.tile-card-body { padding-top: 0; }
.tile-card-meta-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-top: 1.25rem;
}
.tile-card-badge {
  font-size: 0.75rem;
  padding: 2px 8px;
  font-weight: 500;
}
.tile-card-badge-ongoing {
  background: var(--ice-soft);
  color: #8a6c2a;                  /* loft-reserved accent — warm */
}
.tile-card-badge-completed {
  background: var(--ice-tint);
  color: var(--blue);
}
.tile-card-name {
  font-family: "Inter Tight", "Inter", system-ui, sans-serif;
  font-weight: 500;
  font-size: 1.5rem;
  line-height: 1.1;
  color: var(--deep);
  margin: 0.5rem 0 0;
  transition: color var(--transition);
}
.tile-card-slogan {
  font-size: 0.875rem;
  color: var(--muted);
  margin: 0.5rem 0 0;
  line-height: 1.4;
}
.tile-card-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 4px 12px;
  margin: 1rem 0 0;
  padding-top: 1rem;
  border-top: 1px solid var(--line);
  font-size: 0.75rem;
}
.tile-card-stats div { margin: 0; }
.tile-card-stats dt { color: var(--muted); margin: 0; }
.tile-card-stats dd {
  margin: 0;
  font-size: 1rem;
  color: var(--ink);
}

/* ---- Project detail page ----
   Layout follows the prototype: each major block is a full-width
   `<section>` with its own border-bottom across the viewport, and a
   1200px-wide `.project-page-container` centers the content inside.
   Only the gallery section has the --paper background; everything
   else inherits the page bg. */
.project-page { padding: 0; }
.project-section { border-bottom: 1px solid var(--line); }
.project-page-container {
  /* Aligned to the topbar's `max-width: 1400px` + `padding: var(--sp-6)` /
     `3rem` at lg, matching the portfolio + home page boundaries — keeps
     all public pages flush with the logo (left) and rightmost menu
     letter (right). Earlier this was 1200px / px-6-only to mirror the
     prototype's narrower project page; user preference is unified
     navbar alignment instead. */
  max-width: 1400px;
  margin: 0 auto;
  padding: 0 var(--sp-6);
  box-sizing: border-box;
}
@media (min-width: 1024px) {
  .project-page-container { padding: 0 3rem; }
}
.project-section-hero > .project-page-container,
.project-section-description > .project-page-container,
.project-section-lofts > .project-page-container,
.project-section-fitouts > .project-page-container {
  padding-top: 2.5rem;
  padding-bottom: 2.5rem;
}
.project-section-gallery {
  background: var(--paper);
}
.project-section-gallery > .project-page-container {
  padding-top: 1.5rem;
  padding-bottom: 1.5rem;
}
/* Project-hero — 7/5 split mirroring the prototype's
   `grid md:grid-cols-12 gap-6 items-end`. Title block on the left,
   meta-box (Adresas / Studijų / Metai / Plotas as a 2x2) on the right.
   Both columns bottom-align so the meta box's bottom row sits flush
   with the project name's baseline.
   Padding + border-bottom live on the outer `.project-section-hero`
   so the full-width line spans the viewport, not just the container. */
.project-hero {
  display: grid;
  grid-template-columns: 7fr 5fr;
  gap: 1.5rem;
  align-items: end;
}
@media (max-width: 900px) {
  .project-hero { grid-template-columns: 1fr; }
}
.project-header { margin: 0; }
.project-header .label { margin: 0; }
.project-header h1 {
  font-family: "Inter Tight", "Inter", system-ui, sans-serif;
  font-weight: 500; line-height: 1; letter-spacing: -0.02em;
  font-size: clamp(2.25rem, 5vw, 3.75rem);
  color: var(--deep); margin: 0.5rem 0 0;
}
.project-header .project-tagline {
  margin: 0.5rem 0 0; font-size: 1.125rem; color: var(--muted);
}
/* Meta box — 2x2 grid; thin lines between cells matching the
   prototype's `border + grid grid-cols-2 border-r/border-b` look. */
.project-meta {
  margin: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  border: 1px solid var(--line);
  /* No background — prototype's <dl> has none either; the box inherits
     the page bg so it reads as a thin-lined frame, not a paper card. */
  background: transparent;
}
.project-meta > div {
  padding: 1rem 1.25rem;
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.project-meta > div:nth-child(2n) { border-right: 0; }
.project-meta > div:nth-last-child(-n+2) { border-bottom: 0; }
.project-meta dt {
  font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--blue); font-weight: 500;
  margin: 0;
}
.project-meta dd {
  /* Default dd — used by the Address cell (no `.num` class). Normal
     weight + size, sans display-font. The prototype renders the address
     as a plain `<a>` link with no font-weight override. */
  margin: 0.35rem 0 0;
  font-size: 1rem;
  font-weight: 400;
  color: var(--deep);
  line-height: 1.35;
}
.project-meta dd.num {
  /* Numeric stats — Studijų / Metai / Plotas. These use the display
     font + tabular numerals + heavier weight so the values pop visually. */
  font-family: "Inter Tight", "Inter", system-ui, sans-serif;
  font-size: 1.25rem;
  font-weight: 600;
  line-height: 1.2;
}
.project-meta dd a {
  color: inherit;
  font-weight: inherit;                 /* override the default <a> bolding */
}
.project-meta dd a:hover { color: var(--blue); }
@media (max-width: 700px) {
  .project-meta { grid-template-columns: 1fr; }
  .project-meta > div { border-right: 0; }
}
.project-slider {
  /* Slider sits inside .project-section-gallery (var(--paper) bg) so the
     inner frame uses the slightly darker --ice-soft to read as a bezel
     around the photo. No vertical margin — the section's container
     padding handles the top/bottom rhythm. */
  background: var(--ice-soft);
  border: 1px solid var(--line);
  margin: 0;
}
/* Layout: main frame on top with thumbnails stacked beneath in a
   horizontal grid — prototype-matching. (The Įrengimas `.fit-gallery`
   keeps its vertical-right thumb strip; only the project photo slider
   uses the stacked layout.) */
.project-slider-frame { position: relative; aspect-ratio: 16/9; overflow: hidden; }
.project-slider-img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  filter: brightness(1.0) saturate(0.78) contrast(1.02);
}
/* Counter pill, nav arrows, and dot bar — match the in-page `.fit-gallery`
   so the project's main slider and the fit-out galleries read identically. */
.project-slider-counter {
  position: absolute; top: 12px; right: 12px;
  background: rgba(26, 26, 24, 0.78); color: white;
  padding: 4px 10px; border-radius: 999px;
  font-size: 10px; letter-spacing: 0.06em; font-weight: 600;
}
.project-slider-nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 36px; height: 36px; border-radius: 999px;
  background: rgba(255, 255, 255, 0.92); color: var(--ink);
  display: flex; align-items: center; justify-content: center;
  font-size: 20px; line-height: 1;
  box-shadow: 0 4px 14px -4px rgba(58, 52, 42, 0.30);
  cursor: pointer; border: 0; padding: 0;
  transition: background 120ms ease, transform 100ms ease;
}
.project-slider-nav:hover { background: white; }
.project-slider-nav:active { transform: translateY(-50%) scale(0.96); }
.project-slider-prev { left: 12px; }
.project-slider-next { right: 12px; }
.project-slider-dots {
  position: absolute; bottom: 12px; left: 50%;
  transform: translateX(-50%);
  display: flex; gap: 6px;
}
.project-slider-dot {
  width: 7px; height: 7px; border-radius: 999px;
  background: rgba(255, 255, 255, 0.5);
  border: 0; padding: 0; cursor: pointer;
  transition: background 120ms ease, width 120ms ease;
}
.project-slider-dot[aria-current="true"] { background: white; width: 20px; }
/* CSS-side belt for hiding inactive slides — see static/js/project-page.js.
   The HTML `hidden` attribute should be enough on its own, but adding a
   class-based fallback shields the slider against future CSS rules that
   might out-specificity the attribute selector. Either condition hides. */
.project-slider-img[hidden],
.project-slider-img.is-hidden { display: none !important; }
/* Horizontal thumbnail grid below the main frame — prototype-matching:
   square thumbs in a 5-column row, with the grid wrapping on narrower
   widths so a many-photo project stays a single block. Padding adds a
   soft inset around the strip inside the slider's --ice-soft bezel. */
.project-slider-thumbnav {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px;
}
.project-slider-thumbs {
  display: flex;
  flex-wrap: nowrap;
  gap: 8px;
  flex: 1 1 auto;
  min-width: 0;
  overflow-x: auto;
  scroll-behavior: smooth;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.project-slider-thumbs::-webkit-scrollbar { display: none; }
@media (max-width: 640px) {
  .project-slider-thumbnav { gap: 6px; padding: 8px; }
  .project-slider-thumbs { gap: 6px; }
}
.project-slider-thumb {
  /* Exactly five thumbnails fill the strip width (5 thumbs + 4 gaps). */
  flex: 0 0 calc((100% - 4 * 8px) / 5);
  aspect-ratio: 1;
  position: relative; overflow: hidden;
  opacity: 0.55;
  outline: 2px solid transparent; outline-offset: -2px;
  border: 0; padding: 0; background: var(--ice-soft);
  cursor: pointer;
  transition: opacity 150ms ease, outline-color 150ms ease;
}
.project-slider-thumb img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
  filter: brightness(1.0) saturate(0.78) contrast(1.02);
}
.project-slider-thumb:hover { opacity: 0.9; }
.project-slider-thumb[aria-current="true"] { opacity: 1; outline-color: var(--blue); }

/* ---- Floor selector tags ---- */
/* Spacing for the lofts section's heading block — prototype-matching:
   "Pasirink loftą" (small label) sits close to "Loftų sąrašas" (h2);
   h2 has a generous bottom margin (mb-6) before the floor selector. */
.project-section-lofts .label { margin: 0; }
.project-section-lofts h2 {
  margin: 0.5rem 0 1.5rem;
}
.floor-selector {
  display: flex; align-items: center; gap: 0.75rem;
  flex-wrap: wrap;
  /* mb-5 in the prototype — 20px gap between the floor tags and the
     floor plan below. */
  margin: 0 0 1.25rem;
}
.floor-selector-label {
  margin-right: 0.25rem;
}
.floor-buttons { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.floor-btn {
  font-family: inherit;
  font-size: 0.875rem; font-weight: 500; letter-spacing: 0.02em;
  padding: 0.5rem 1rem;
  background: var(--paper);
  color: var(--deep);
  border: 1px solid var(--line);
  border-radius: 6px;
  cursor: pointer;
  transition: background var(--transition), border-color var(--transition), color var(--transition);
}
.floor-btn:hover { border-color: var(--blue); color: var(--blue); }
.floor-btn[aria-current="true"] {
  background: var(--deep); color: var(--paper); border-color: var(--deep);
}

/* Hide the inactive floor panel(s) — JS swaps `hidden` based on the
   clicked .floor-btn (see static/js/project-page.js). */
.project-floor-panel[hidden] { display: none !important; }

/* Apie projektą — prototype-matching 3/9 grid: small uppercase label on
   the left, description prose on the right. Collapses to a single
   column on narrow screens. Padding + bottom-border live on the outer
   `.project-section-description` wrapper. */
.project-description-grid {
  display: grid;
  grid-template-columns: 3fr 9fr;
  gap: 1.5rem;
  align-items: start;
}
@media (max-width: 768px) {
  .project-description-grid { grid-template-columns: 1fr; gap: 0.75rem; }
}
.project-description .label { margin: 0; padding-top: 0.4rem; }
.project-description .prose {
  font-size: 1.125rem; line-height: 1.4; color: var(--ink);
}
.project-description .prose p { margin: 0 0 1rem; color: var(--ink); }
.project-description .prose p:last-child { margin-bottom: 0; }

.project-lofts {
  /* Padding/border lives on .project-section-lofts wrapper; nothing
     to do here beyond stacking children. */
  padding: 0;
}
.project-floor { margin-top: var(--sp-6); }
/* Floor plan — full available width, rounded corners, soft border;
   matches the prototype's `border rounded-lg overflow-hidden` figure. */
.project-floor-plan {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 8px;
  overflow: hidden;
  margin: 0;
}
.project-floor-plan img { display: block; width: 100%; height: auto; }

/* Rounded card around the loft table — clips the table's top/bottom
   corners to the wrapper's border-radius. `overflow-x: auto` lets the
   table scroll sideways on narrow screens without breaking the rounded
   container the way `overflow: hidden` would. */
.loft-table-wrap {
  margin-top: 2rem;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 8px;
  overflow-x: auto;
}
.loft-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  /* Pin column widths so swapping floors (with different "Būsena"
     values, or longer/shorter Kryptis text) doesn't reshuffle the
     columns. Cells with overflowing content still ellipsize cleanly. */
  table-layout: fixed;
  margin: 0;
}
.loft-table th,
.loft-table td {
  padding: 14px 16px;
  border-bottom: 1px solid var(--line);
  text-align: left;
}
.loft-table tbody tr:last-child td { border-bottom: 0; }
.loft-table thead th {
  background: var(--ice-soft);
  font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase;
  font-weight: 600;
  color: var(--muted);
}
.loft-table thead th:first-child { border-top-left-radius: 8px; }
.loft-table thead th:last-child  { border-top-right-radius: 8px; }
/* Per-column emphasis — `Lofto Nr.` and `Kaina` read as the primary
   identifiers, so they're heavier; numeric columns use tabular-nums
   so digits line up across rows. */
.loft-table tbody td:nth-child(1) {
  font-weight: 600; color: var(--deep);
  font-variant-numeric: tabular-nums;
}
.loft-table tbody td:nth-child(2) { font-variant-numeric: tabular-nums; }
.loft-table tbody td:nth-child(3) { color: var(--muted); }
.loft-table tbody td:nth-child(4) {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
/* Row hover — light tan tint matching the prototype. */
.loft-table tbody tr { transition: background 100ms ease; }
.loft-table tbody tr:hover { background: var(--ice-soft); }
.loft-state { display: inline-block; padding: 3px 10px; border-radius: 999px; font-size: 11px; font-weight: 600; }
.loft-state-available { background: #dde4d8; color: var(--loft-available-fg); }
.loft-state-reserved { background: #e8e0cc; color: var(--loft-reserved-fg); }
.loft-state-sold { background: #e2dcd6; color: var(--loft-sold-fg); }

/* ---- Įrengimas section on project page ----
   Prototype-matching: small h2, row of pill-style tab buttons, then a
   single bordered panel that flips between Įrengimas items. Each
   panel is a 5/7 grid (text left with border-right, gallery right).
   The full-width section wrapper (`.project-section-fitouts`) supplies
   the --ice-soft background + border-bottom across the viewport. */
.project-section-fitouts { background: var(--ice-soft); }
.project-fitouts {
  /* No own padding/border — the outer section handles it. */
  padding: 0;
}
.project-fitouts-h2 {
  font-family: "Inter Tight", "Inter", system-ui, sans-serif;
  font-weight: 500; line-height: 0.96; letter-spacing: -0.025em;
  color: var(--deep);
  font-size: clamp(1.5rem, 3vw, 1.875rem);
  margin: 0 0 1.5rem;
}

/* Tab strip — pill-shaped outlined buttons; active = deep on paper. */
.fit-tabs {
  display: flex; flex-wrap: wrap; gap: 0.5rem;
  margin: 0 0 1.5rem;
}
.fit-tab {
  font-family: inherit;
  font-size: 0.875rem; font-weight: 500; letter-spacing: 0.02em;
  padding: 0.5rem 1rem;
  background: var(--paper);
  color: var(--deep);
  border: 1px solid var(--line);
  /* Square corners to match the prototype's fit-tab styling. */
  border-radius: 0;
  cursor: pointer;
  transition: background var(--transition), border-color var(--transition), color var(--transition);
}
.fit-tab:hover { border-color: var(--blue); color: var(--blue); }
.fit-tab[aria-current="true"] {
  background: var(--deep); color: var(--paper); border-color: var(--deep);
}

/* Panel container — each shown panel IS the card (paper bg, border).
   Cards stack but only one is visible at a time (others have [hidden]
   set by the tab JS); switching tabs swaps which card is on screen. */
.fit-panels {
  /* The wrapper itself is invisible — cards are individually framed. */
  background: transparent;
  border: 0;
}
.fit-panel {
  background: var(--paper);
  border: 1px solid var(--line);
  display: grid;
  /* `minmax(0, …fr)` lets each column shrink below its intrinsic
     content width (long words in the prose column would otherwise
     blow out the grid track and push the panel past its border).
     `align-items: start` keeps the gallery anchored at the top while
     the prose column is free to grow taller — without this the gallery's
     `aspect-ratio: 2/1` was capping the row height and the prose
     overflowed visibly past the panel's bottom border. */
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  align-items: start;
  gap: 0;
}
/* `display: grid` above wins against the user-agent stylesheet's
   `[hidden] { display: none }`. Without this explicit override every
   `.fit-panel[hidden]` (inactive tab) would still render and the three
   panels would stack visibly instead of swapping cleanly. Same trick
   used in `.project-slider-img[hidden]` for the photo slider. */
.fit-panel[hidden] { display: none !important; }
/* Panel that contains ONLY text (no gallery) — collapse to single col
   so the prose fills the whole card instead of leaving the right 7/12
   blank. The `:not(:has(.fit-gallery))` selector matches because the
   gallery is only rendered when the Įrengimas item has photos. */
.fit-panel:not(:has(.fit-gallery)) { grid-template-columns: 1fr; }
.fit-panel:not(:has(.fit-gallery)) .fit-panel-text { border-right: 0; }
@media (max-width: 900px) {
  .fit-panel { grid-template-columns: 1fr; }
}
.fit-panel-text {
  padding: 1.5rem 1.75rem;
  border-right: 1px solid var(--line);
}
@media (max-width: 900px) {
  .fit-panel-text { border-right: 0; border-bottom: 1px solid var(--line); }
}
.fit-panel-tagline {
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--blue);
  margin: 0 0 0.75rem;
}
.fit-panel-body {
  font-size: 1rem; line-height: 1.5; color: var(--ink);
}
.fit-panel-body p { margin: 0 0 0.75rem; color: var(--ink); }
.fit-panel-body p:last-child { margin-bottom: 0; }
.fit-panel-body ul {
  list-style: none; padding: 0; margin: 1rem 0 0;
  font-size: 0.875rem;
}
.fit-panel-body ul li {
  position: relative; padding-left: 1.25rem;
  margin: 0.25rem 0; line-height: 1.45;
}
.fit-panel-body ul li::before {
  content: "+";
  position: absolute; left: 0; top: 0;
  color: var(--blue);
  font-weight: 600;
}

/* Gallery: prototype's `1fr / 76px` grid — main image left, vertical
   thumb strip right; 2:1 aspect on desktop, looser on narrow. */
/* Column layout — main image on top, horizontal thumb row beneath.
   The main image owns the aspect ratio now (the gallery used to set
   `aspect-ratio: 2/1` on the whole grid, which couldn't accommodate
   a thumb row underneath the main image without distorting it). */
.fit-gallery {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 0.5rem;
  background: var(--ice-soft);
}
.fit-gallery-main {
  position: relative;
  overflow: hidden;
  aspect-ratio: 2 / 1;
  background: var(--ice-soft);
  border: 1px solid var(--line);
}
@media (max-width: 768px) {
  .fit-gallery-main { aspect-ratio: 4 / 3; }
}
.fit-gallery-img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  filter: brightness(1.0) saturate(0.78) contrast(1.02);
  display: block;
}
.fit-gallery-img[hidden] { display: none; }
.fit-gallery-counter {
  position: absolute; top: 12px; right: 12px;
  background: rgba(26, 26, 24, 0.78); color: white;
  padding: 4px 10px; border-radius: 999px;
  font-size: 10px; letter-spacing: 0.06em; font-weight: 600;
}
.fit-gallery-nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 36px; height: 36px; border-radius: 999px;
  background: rgba(255, 255, 255, 0.92); color: var(--ink);
  display: flex; align-items: center; justify-content: center;
  font-size: 20px; line-height: 1;
  box-shadow: 0 4px 14px -4px rgba(58, 52, 42, 0.30);
  cursor: pointer; border: 0; padding: 0;
  transition: background 120ms ease, transform 100ms ease;
}
.fit-gallery-nav:hover { background: white; }
.fit-gallery-nav:active { transform: translateY(-50%) scale(0.96); }
.fit-gallery-prev { left: 12px; }
.fit-gallery-next { right: 12px; }
.fit-gallery-dots {
  position: absolute; bottom: 12px; left: 50%;
  transform: translateX(-50%);
  display: flex; gap: 6px;
}
.fit-gallery-dot {
  width: 7px; height: 7px; border-radius: 999px;
  background: rgba(255, 255, 255, 0.5);
  border: 0; padding: 0; cursor: pointer;
  transition: background 120ms ease, width 120ms ease;
}
.fit-gallery-dot[aria-current="true"] { background: white; width: 20px; }

/* Horizontal thumbnail row — a single scrollable strip so a fit-out with
   many photos keeps all thumbnails on one line (scroll left/right) rather
   than wrapping into stacked rows. Square thumbs. */
.fit-gallery-thumbnav {
  display: flex;
  align-items: center;
  gap: 6px;
}
.fit-gallery-thumbs {
  display: flex;
  flex-wrap: nowrap;
  gap: 6px;
  flex: 1 1 auto;
  min-width: 0;
  overflow-x: auto;
  scroll-behavior: smooth;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.fit-gallery-thumbs::-webkit-scrollbar { display: none; }
.fit-gallery-thumb {
  /* Exactly five thumbnails fill the strip width (5 thumbs + 4 gaps). */
  flex: 0 0 calc((100% - 4 * 6px) / 5);
  aspect-ratio: 1;
  position: relative; overflow: hidden;
  cursor: pointer; opacity: 0.55;
  outline: 2px solid transparent; outline-offset: -2px;
  border: 0; padding: 0; background: var(--ice-soft);
  transition: opacity 150ms ease, outline-color 150ms ease;
}
.fit-gallery-thumb img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  filter: brightness(1.0) saturate(0.78) contrast(1.02);
}
.fit-gallery-thumb:hover { opacity: 0.9; }
.fit-gallery-thumb[aria-current="true"] {
  opacity: 1;
  outline-color: var(--blue);
}

/* ---- Floor plan zoom modal (JS-driven, see static/js/project-page.js) --- */
.floor-plan-btn {
  display: block; width: 100%;
  background: transparent; border: 0; padding: 0;
  cursor: zoom-in;
  transition: filter var(--transition);
}
.floor-plan-btn:hover { filter: brightness(0.97); }
.floor-plan-btn:focus-visible { outline: 3px solid var(--blue); outline-offset: -3px; }
.fp-modal {
  position: fixed; inset: 0; z-index: 1000;
  display: flex; flex-direction: column;
  background: rgba(26, 26, 24, 0.92);
  opacity: 0; pointer-events: none;
  transition: opacity 0.2s ease;
}
.fp-modal.open { opacity: 1; pointer-events: auto; }
.fp-modal-bar {
  flex-shrink: 0;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 14px 24px;
  background: rgba(26, 26, 24, 0.6);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  color: white;
}
.fp-modal-title {
  font-size: 0.875rem; letter-spacing: 0.04em;
  text-transform: uppercase; font-weight: 500;
}
.fp-modal-actions {
  display: flex; align-items: center; gap: 0.5rem;
}
.fp-modal-btn {
  background: transparent; color: white;
  border: 1px solid rgba(255, 255, 255, 0.4);
  padding: 0.4rem 1rem; font: inherit; font-size: 0.875rem;
  cursor: pointer; transition: background var(--transition);
}
.fp-modal-btn:hover { background: rgba(255, 255, 255, 0.12); }
.fp-modal-close { padding: 0.4rem 0.75rem; }
.fp-modal-body {
  flex: 1; min-height: 0;
  display: flex; align-items: center; justify-content: center;
  overflow: auto;
  -webkit-overflow-scrolling: touch;
  padding: 1.5rem;
}
.fp-modal-body img {
  background: white;
  display: block;
}
/* Two zoom states. "fit" scales the image to the viewport (default
   open state); "actual" lets it render at its natural size with the
   body overflowing — momentum-scroll lets mobile users pan a zoomed-in
   image around. Click the image (or the toggle button) to swap. */
.fp-modal[data-zoom="fit"] .fp-modal-body img {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
  cursor: zoom-in;
}
.fp-modal[data-zoom="actual"] .fp-modal-body {
  align-items: flex-start;
  justify-content: flex-start;
}
.fp-modal[data-zoom="actual"] .fp-modal-body img {
  max-width: none;
  max-height: none;
  width: auto;
  height: auto;
  cursor: zoom-out;
}
/* Lock background scroll while the modal is open (set by JS on <html>). */
.fp-modal-no-scroll { overflow: hidden; }

/* ---- Composer-Įrengimas grid ---- */
.composer-irengimas .irengimas-card {
  background: var(--paper); border: 1px solid var(--line); padding: var(--sp-6);
  /* Hover mirrors the prototype's `.fitout-card`: subtle ice-tint
     wash + blue border + soft drop shadow. No vertical shift, so
     the card grid layout doesn't jump when the cursor enters. */
  transition: background var(--transition), border-color var(--transition), box-shadow var(--transition);
  /* The card is NOT a link — keep the default text cursor over the
     body content so it doesn't misleadingly suggest clickability. */
  cursor: default;
}
.composer-irengimas .irengimas-card:hover {
  background: var(--ice-tint);
  border-color: var(--blue);
  box-shadow: 0 6px 16px -8px rgba(58, 52, 42, 0.18);
}
.composer-irengimas .irengimas-text { margin-top: var(--sp-3); font-size: 0.95rem; }
/* Prototype bullet style — `<li class="flex gap-2"><span class="blue">+</span>…</li>`.
   Drop the browser disc bullet; render a blue "+" via ::marker. Tight
   row spacing (≈0.375rem) and 0.5rem gap between marker + text. */
.composer-irengimas .irengimas-text ul {
  list-style: none;
  padding: 0;
  margin: 1rem 0 0;
  font-size: 0.875rem;
  color: var(--ink);
}
.composer-irengimas .irengimas-text ul li {
  position: relative;
  padding-left: 1.25rem;
  margin: 0.375rem 0;
  line-height: 1.45;
}
.composer-irengimas .irengimas-text ul li::before {
  content: "+";
  position: absolute;
  left: 0; top: 0;
  color: var(--blue);
  font-weight: 600;
}
/* Plain paragraphs inside the Įrengimas text get the prototype's
   muted leading-relaxed treatment. */
.composer-irengimas .irengimas-text p {
  color: var(--muted);
  line-height: 1.55;
  margin: 0 0 0.75rem;
}
.composer-irengimas .irengimas-text p:last-child { margin-bottom: 0; }
/* The Įrengimas item's `slogan` (admin-curated tagline above the
   text) takes the warm accent color, matching the prototype's
   `<p class="text-sm blue mt-2 font-medium">`. */
.composer-irengimas .irengimas-card .muted {
  /* The tagline reuses the .muted class today; promote it to the
     prototype's accent color when it sits directly under the card's h3.
     Scoped tightly so the broader .muted text on other cards stays
     unchanged. */
  color: var(--blue);
  font-size: 0.875rem;
  font-weight: 500;
  margin-top: 0.5rem;
}

/* ---- Composer-Investuotojams ---- */
.investuotojams-grid { display: grid; grid-template-columns: 5fr 7fr; gap: var(--sp-10); }
@media (max-width: 900px) { .investuotojams-grid { grid-template-columns: 1fr; } }
.investuotojams-header h2 {
  /* Prototype: `display text-5xl md:text-6xl` ≈ 3rem → 3.75rem.
     Use the same display-font + tight tracking as the centered area
     headings so the typography reads as part of the same family. */
  font-family: "Inter Tight", "Inter", system-ui, sans-serif;
  font-weight: 500;
  line-height: 0.96;
  letter-spacing: -0.025em;
  color: var(--deep);
  font-size: clamp(2.5rem, 5vw, 3.75rem);
  margin: 0.75rem 0 0;
}
.investuotojams-table {
  background: var(--paper); border: 1px solid var(--line);
  padding: 0 var(--sp-6);
  display: grid; grid-template-columns: 1fr auto; column-gap: var(--sp-8);
}
.investuotojams-table .inv-row { display: contents; }
.investuotojams-table dt, .investuotojams-table dd {
  padding: var(--sp-5) 0; border-bottom: 1px solid var(--line);
  align-self: center; margin: 0;
}
.investuotojams-table .inv-row:last-of-type dt,
.investuotojams-table .inv-row:last-of-type dd { border-bottom: 0; }
.investuotojams-table dt { font-weight: 500; color: var(--ink); }
.investuotojams-table dd {
  text-align: right; font-family: "Inter Tight", system-ui, sans-serif;
  font-weight: 600; font-size: 1.4rem; color: var(--deep);
  font-variant-numeric: tabular-nums;
}

/* ---- Composer-static_page ---- */
.composer-static-grid { display: grid; grid-template-columns: 4fr 8fr; gap: var(--sp-10); }
@media (max-width: 900px) { .composer-static-grid { grid-template-columns: 1fr; } }
.composer-static-header h2 {
  /* Match Investuotojams / Kontaktai prototype heading scale —
     `display text-5xl md:text-6xl`. */
  font-family: "Inter Tight", "Inter", system-ui, sans-serif;
  font-weight: 500;
  line-height: 0.96;
  letter-spacing: -0.025em;
  color: var(--deep);
  font-size: clamp(2.5rem, 5vw, 3.75rem);
  margin: 0.75rem 0 0;
}

/* ---- Contact section (betonas overrides) ----
   The shared template's `.contact-form` shipped with a white/rounded
   look that doesn't match the prototype. On the public site we want:
     - 5/7 info-vs-form grid (single column under 900px)
     - Form card sits on --ice-tint with a 1px line border (square corners)
     - Inputs sit on --paper with --line borders + dark focus ring
     - Labels above each field in the same uppercase tracked .label style
       used elsewhere (matches the prototype's <span class="label">)
   Scoped under body:not(.admin) so the admin chrome stays unchanged. */
body:not(.admin) .contact {
  background: var(--paper);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  padding: 6rem 0;
}
/* Aligned to the topbar's 1400px + var(--sp-6)→3rem padding so the
   contact section's left/right boundaries sit flush with the logo +
   rightmost menu letter on every page that auto-includes it. */
body:not(.admin) .contact > .container {
  max-width: 1400px;
  padding: 0 var(--sp-6);
  box-sizing: border-box;
}
@media (min-width: 1024px) {
  body:not(.admin) .contact > .container { padding: 0 3rem; }
}
body:not(.admin) .contact-grid {
  grid-template-columns: 5fr 7fr;
  gap: 2.5rem;
}
@media (max-width: 900px) {
  body:not(.admin) .contact-grid { grid-template-columns: 1fr; gap: var(--sp-8); }
}
body:not(.admin) .contact-info .label {
  display: block; margin-bottom: 0.75rem;
}
body:not(.admin) .contact-info h2 {
  /* Same as Investuotojams / Apie mus headings — `display text-5xl md:text-6xl`. */
  font-family: "Inter Tight", "Inter", system-ui, sans-serif;
  font-weight: 500;
  line-height: 0.96;
  letter-spacing: -0.025em;
  color: var(--deep);
  font-size: clamp(2.5rem, 5vw, 3.75rem);
  margin: 0.75rem 0 0;
}
body:not(.admin) .contact-info .contact-subtitle {
  font-size: 1.125rem; color: var(--muted);
  margin: 1.5rem 0 0; max-width: 28rem;
}
body:not(.admin) .contact-info .contact-meta {
  margin-top: 2rem; font-size: 1rem; line-height: 1.5; color: var(--ink);
}
body:not(.admin) .contact-info .contact-meta a { color: var(--ink); }
body:not(.admin) .contact-info .contact-meta a:hover { color: var(--blue); }
/* The shared kontaktai.html still ships the legacy `<ul class="contact-details">`
   pattern; reuse the contact-meta typography for it so the layout reads the same. */
body:not(.admin) .contact-info .contact-details {
  margin-top: 2rem; padding: 0; list-style: none;
  font-size: 1rem; line-height: 1.5; color: var(--ink);
  display: block;
}
body:not(.admin) .contact-info .contact-details li {
  display: block; grid-template-columns: none;
  border: 0; padding: 0; gap: 0;
}
body:not(.admin) .contact-info .contact-details .company-details {
  color: var(--ink); line-height: 1.5;
}

/* The form card itself. */
body:not(.admin) .contact-form {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.25rem;
  background: var(--ice-tint);
  border: 1px solid var(--line);
  border-radius: 0;
  box-shadow: none;
  padding: 2rem;
}
@media (max-width: 600px) {
  body:not(.admin) .contact-form { grid-template-columns: 1fr; padding: 1.5rem; }
}
body:not(.admin) .contact-form label {
  display: block; position: relative;
  font-size: 0.95rem; font-weight: 400; color: var(--ink);
  grid-column: auto;
}
body:not(.admin) .contact-form .field-label-text {
  display: block;
  font-family: "Inter Tight", "Inter", system-ui, sans-serif;
  font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--blue); font-weight: 500;
  margin: 0 0 0.4rem;
}
body:not(.admin) .contact-form .required-mark { color: var(--blue); }

/* Span the full row width for email, message, and subject fields.
   Email gets its own row above the textarea so users don't have to type
   a long address into a half-width input — the form's two-column grid
   doesn't have enough room for both. The `body:not(.admin) .contact-form
   label` rule above resets every label to `grid-column: auto`, so each
   field that needs to span has to be listed here explicitly. */
body:not(.admin) .contact-form label[data-field="message"] {
  grid-column: 1 / -1;
}
/* Honeypot stays full-width but invisible — base .honeypot rules already
   take it out of the layout. */
body:not(.admin) .contact-form input,
body:not(.admin) .contact-form textarea,
body:not(.admin) .contact-form select {
  display: block; width: 100%;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 0;
  padding: 0.7rem 0.85rem;
  font-size: 0.95rem;
  color: var(--ink);
  transition: border-color var(--transition), box-shadow var(--transition);
}
body:not(.admin) .contact-form input:focus,
body:not(.admin) .contact-form textarea:focus,
body:not(.admin) .contact-form select:focus {
  outline: none;
  border-color: var(--deep);
  box-shadow: 0 0 0 3px rgba(58, 52, 42, 0.12);
}
body:not(.admin) .contact-form textarea { min-height: 110px; resize: vertical; }

/* Drop the absolute-positioned asterisk overlay from the shared CSS —
   we now render the asterisk inline in the visible label text. */
body:not(.admin) .contact-form label.is-required:has(input:placeholder-shown, textarea:placeholder-shown)::after {
  content: none;
}

body:not(.admin) .contact-form .contact-submit-row {
  grid-column: 1 / -1; margin-top: 0.25rem;
}
body:not(.admin) .contact-form button[type="submit"] {
  background: var(--deep); color: var(--paper);
  border: 0; border-radius: 0;
  padding: 0.85rem 1.75rem;
  font-size: 0.875rem; font-weight: 500; letter-spacing: 0.04em;
  cursor: pointer; transition: background var(--transition);
}
body:not(.admin) .contact-form button[type="submit"]:hover { background: var(--blue); }

/* When the composer renders the contact form area, the wrapping
   `.composer-area` adds its own 6rem padding + light-paper bg. Suppress
   the alternating-row paper bg so the contact area doesn't double up
   visually against the universal `.contact` styling, and drop the
   centered header rules that don't apply to this 5/7 layout. */
body:not(.admin) .composer-contact { background: var(--paper); }
body:not(.admin) .composer-contact .contact-info > h2 { text-align: left; }

/* ---- Page slogan (Slice 1) ---- */
.page-slogan {
  font-size: clamp(1.25rem, 2vw, 1.75rem);
  color: var(--deep); line-height: 1.4; margin: var(--sp-5) 0;
}

/* ---- Kontaktai page ---- */
.kontaktai-page { padding: var(--sp-12) 0; }
/* Override the default `.container` (1100px) so the Kontaktai page's
   header + team grid line up with the topbar's logo / rightmost menu
   letter, matching every other public page. */
.kontaktai-page > .container {
  max-width: 1400px;
  padding: 0 var(--sp-6);
  box-sizing: border-box;
}
@media (min-width: 1024px) {
  .kontaktai-page > .container { padding: 0 3rem; }
}
.kontaktai-header h1 {
  font-family: "Inter Tight", system-ui, sans-serif; font-weight: 500;
  font-size: clamp(2.5rem, 6vw, 4.5rem); color: var(--deep); margin: var(--sp-3) 0;
}
.team-grid {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--sp-6);
  margin-top: var(--sp-10);
}
@media (max-width: 900px) { .team-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 600px) { .team-grid { grid-template-columns: 1fr; } }
.team-card { background: var(--paper); border: 1px solid var(--line); padding: var(--sp-5); }
.team-card-photo {
  aspect-ratio: 1; background: var(--ice-soft); overflow: hidden; margin-bottom: var(--sp-4);
}
.team-card-photo img {
  width: 100%; height: 100%; object-fit: cover;
  filter: brightness(1.0) saturate(0.78) contrast(1.02);
}
.team-card h3 {
  font-family: "Inter Tight", system-ui, sans-serif; color: var(--deep);
  margin: var(--sp-2) 0;
}

/* ---- Footer rebuild (Slice 5) ----
   The template's shared `.site-footer` defaults to a dark slate background
   (designed for the FastAPI template's blue palette). The prototype uses
   a transparent footer on the same `--bg` color as the page, with a thin
   top line, sand-toned text, and a 1400px-wide container — matching the
   topbar's width. Scope everything to body:not(.admin) so the admin
   keeps its own dark sidebar footer styling. */
body:not(.admin) .site-footer {
  background: transparent;
  color: var(--muted);
  border-top: 1px solid var(--line);
  padding: 2.5rem 0;
  margin-top: 0;
  box-shadow: none;
}
body:not(.admin) .site-footer > .container {
  max-width: 1400px;
  padding-left: var(--sp-6); padding-right: var(--sp-6);
}
@media (min-width: 1024px) {
  body:not(.admin) .site-footer > .container {
    padding-left: 3rem; padding-right: 3rem;
  }
}
body:not(.admin) .site-footer a { color: var(--muted); }
body:not(.admin) .site-footer a:hover { color: var(--blue); }

body:not(.admin) .site-footer .footer-grid {
  display: grid; grid-template-columns: 1fr 1fr 1fr;
  align-items: center; gap: var(--sp-6);
}
@media (max-width: 700px) {
  body:not(.admin) .site-footer .footer-grid {
    grid-template-columns: 1fr; text-align: center; gap: var(--sp-4);
  }
}
body:not(.admin) .footer-logo { display: inline-block; line-height: 0; }
body:not(.admin) .footer-logo img { height: 32px; width: auto; }
/* Mobile: hide the footer logo entirely. The footer's three-column
   layout collapses to a single stack on phones, where the logo at the
   top of the stack feels redundant against the navbar brand. */
@media (max-width: 768px) {
  body:not(.admin) .footer-logo { display: none; }
}
body:not(.admin) .footer-logo span {
  font-family: "Inter Tight", "Inter", system-ui, sans-serif;
  font-weight: 600; color: var(--deep); font-size: 1.125rem;
  letter-spacing: -0.01em;
}
body:not(.admin) .footer-socials {
  list-style: none; padding: 0; margin: 0;
  display: flex; gap: var(--sp-4); justify-content: center;
}
body:not(.admin) .footer-socials a {
  color: var(--muted);
  display: inline-flex; width: 36px; height: 36px;
  align-items: center; justify-content: center;
  transition: color var(--transition);
}
body:not(.admin) .footer-socials a:hover { color: var(--blue); }
body:not(.admin) .footer-copyright {
  text-align: right; font-size: 0.875rem; color: var(--muted);
}
@media (max-width: 700px) { body:not(.admin) .footer-copyright { text-align: center; } }

/* Footer-pages strip — already-styled by the template's shared
   .footer-pages rules; only the colors need rebasing onto the
   betonas palette. */
body:not(.admin) .site-footer .footer-pages {
  list-style: none; margin: 0 0 1.5rem; padding: 0 0 1.5rem;
  display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-4);
  align-items: center; font-size: 0.875rem;
  border-bottom: 1px solid var(--line);
}
body:not(.admin) .site-footer .footer-pages li { color: var(--muted); }
body:not(.admin) .site-footer .footer-pages li:not(:last-child)::after {
  background: var(--line);
}
body:not(.admin) .site-footer .footer-pages a { color: var(--muted); }
body:not(.admin) .site-footer .footer-pages a:hover { color: var(--blue); }
body:not(.admin) .site-footer .copyright {
  border-top: 0; padding-top: 0; margin-top: 0;
  font-size: 0.875rem; color: var(--muted);
}

/* ---- Cookie consent bar ---- */
.cookie-consent {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 1000;
  background: var(--color-surface, #fff);
  border-top: 1px solid var(--line, #ddd);
  box-shadow: 0 -4px 16px -8px rgba(0, 0, 0, 0.25);
  padding: clamp(12px, 2vw, 20px);
}
.cookie-consent[hidden] { display: none !important; }
.cookie-consent-inner {
  max-width: 1100px;
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 24px;
  justify-content: space-between;
}
.cookie-consent-text { margin: 0; font-size: 14px; max-width: 70ch; }
.cookie-consent-actions { display: flex; gap: 8px; flex: 0 0 auto; }
@media (max-width: 640px) {
  .cookie-consent-inner { flex-direction: column; align-items: stretch; }
  .cookie-consent-actions { justify-content: flex-end; }
}

/* ---- Gallery thumbnail scroll arrows (project slider + fit gallery) ---- */
.thumbnav-arrow {
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: white;
  color: var(--ink);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  box-shadow: 0 2px 8px -4px rgba(58, 52, 42, 0.30);
  transition: opacity 120ms ease, background 120ms ease;
}
.thumbnav-arrow:hover { background: var(--ice-soft); }
.thumbnav-arrow[hidden] { display: none; }
.thumbnav-arrow:disabled { opacity: 0.3; cursor: default; box-shadow: none; }
