/* ==========================================================================
   Grum Urban Gallery — Urban Art
   Design tokens are fixed; see design_handoff_grum_urban_gallery/README.md.
   No border radius anywhere. No shadows. Wide uppercase letter-spacing is
   the identity.
   ========================================================================== */

/* ---- Montserrat ---------------------------------------------------------- */

/* Self-hosted, not fetched from Google: no third-party request on any page
   view, so no visitor IP leaves for fonts.gstatic.com, and the static export
   stays self-contained. These are the variable files — one download covers
   every weight the design uses (300 through 700), which is why the rules say
   `font-weight: 300 700` rather than one @font-face per weight.
   Two subsets: latin, and latin-ext for the Slovenian č/š/ž. The
   unicode-range values come straight from the Google Fonts CSS. */

@font-face {
  font-family: "Montserrat";
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("../fonts/montserrat-latin-ext.woff2") format("woff2");
  unicode-range:
    U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
    U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB,
    U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Montserrat";
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("../fonts/montserrat-latin.woff2") format("woff2");
  unicode-range:
    U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212,
    U+2215, U+FEFF, U+FFFD;
}

:root {
  --bg: #0a0a0a;
  --surface: #141414;
  --border: #2a2a2a;
  --hairline: #1c1c1c;

  --text: #f2efe9;
  --body: #d8d3ca;
  --muted: #8f8a82;
  --faint: #565249;

  --gold: #c9963f;
  --gold-hover: #e0b563;
  --error: #d2705a;
}

/* ---- Base ---------------------------------------------------------------- */

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

html,
body {
  margin: 0;
  padding: 0;
  background: var(--bg);
}

body {
  font-family: "Montserrat", Helvetica, Arial, sans-serif;
  color: var(--text);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

a {
  color: var(--gold);
  text-decoration: none;
}
a:hover {
  color: var(--gold-hover);
}

img {
  max-width: 100%;
}

::selection {
  background: var(--gold);
  color: var(--bg);
}

input:focus,
textarea:focus,
select:focus {
  outline: 1px solid var(--gold);
}

a:focus-visible,
button:focus-visible {
  outline: 1px solid var(--gold);
  outline-offset: 4px;
}

@keyframes fadeUp {
  from {
    opacity: 0;
    transform: translateY(14px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
@keyframes fadeOut {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}

/* Lightbox: a touch of scale on top of the house fadeUp, so it reads as
   coming forward rather than sliding. */
@keyframes lightboxIn {
  from {
    opacity: 0;
    transform: translateY(18px) scale(0.985);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}
@keyframes lightboxOut {
  from {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
  to {
    opacity: 0;
    transform: translateY(8px) scale(0.992);
  }
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--gold);
  color: var(--bg);
  padding: 12px 18px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}
.skip-link:focus {
  left: 0;
  color: var(--bg);
}

.shell {
  min-height: 100vh;
  min-height: 100svh;
  background: var(--bg);
  display: flex;
  flex-direction: column;
}

/* ---- Fixed header -------------------------------------------------------- */

.site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 22px 28px;
  /* Opaque so scrolled content never runs underneath the header. */
  background: var(--bg);
  border-bottom: 1px solid var(--hairline);
  pointer-events: auto;
}

/* Domov has nothing to scroll under the bar, so it keeps the bare look. */
body.page-domov .site-header {
  background: transparent;
  border-bottom-color: transparent;
  pointer-events: none;
}
body.page-domov .wordmark,
body.page-domov .menu-toggle {
  pointer-events: auto;
}

/* The hairline would otherwise cut across the open menu overlay. */
body.menu-open .site-header {
  border-bottom-color: transparent;
}

.wordmark {
  display: flex;
  align-items: center;
}
.wordmark img {
  display: block;
  height: 30px;
  width: auto;
}

/* Domov shows only the big logo and the hamburger — until the menu opens. */
body.page-domov .wordmark {
  visibility: hidden;
}
body.page-domov.menu-open .wordmark {
  visibility: visible;
}

.menu-toggle {
  pointer-events: auto;
  background: none;
  border: none;
  cursor: pointer;
  padding: 10px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  align-items: flex-end;
  margin-left: auto;
}
.menu-toggle span {
  display: block;
  height: 2px;
  background: var(--text);
  transition:
    transform 0.3s,
    background 0.3s,
    opacity 0.3s;
}
.menu-toggle span:nth-child(1),
.menu-toggle span:nth-child(3) {
  width: 30px;
}
.menu-toggle span:nth-child(2) {
  width: 22px;
}

body.menu-open .menu-toggle span {
  background: var(--gold);
}
body.menu-open .menu-toggle span:nth-child(1) {
  transform: translateY(8px) rotate(45deg);
}
body.menu-open .menu-toggle span:nth-child(2) {
  opacity: 0;
}
body.menu-open .menu-toggle span:nth-child(3) {
  transform: translateY(-8px) rotate(-45deg);
}

/* ---- Menu overlay -------------------------------------------------------- */

.menu-overlay {
  position: fixed;
  inset: 0;
  z-index: 40;
  background: rgba(10, 10, 10, 0.97);
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
.menu-overlay[hidden] {
  display: none;
}
body.menu-open .menu-overlay {
  display: flex;
}

.menu-link {
  font-size: 34px;
  font-weight: 300;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--text);
  padding: 14px 20px;
}
.menu-link:hover {
  color: var(--gold);
}
.menu-link.is-active {
  color: var(--gold);
}
body.menu-open .menu-link {
  animation: fadeUp 0.4s ease both;
}

.menu-rule {
  margin-top: 36px;
  width: 120px;
  height: 1px;
  background: var(--gold);
  opacity: 0.6;
}

/* Without JS the overlay cannot be toggled, so lay the nav out inline. */
html.no-js .menu-overlay {
  display: flex;
  position: static;
  background: transparent;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: center;
  padding: 76px 20px 0;
  gap: 0;
}
html.no-js .menu-link {
  font-size: 13px;
  letter-spacing: 0.2em;
  padding: 8px 14px;
}
html.no-js .menu-rule,
html.no-js .menu-toggle {
  display: none;
}

/* ---- Page shells --------------------------------------------------------- */

.page {
  flex: 1;
  width: 100%;
  margin: 0 auto;
  padding: 130px 40px 80px;
}
.page--gallery {
  max-width: 1240px;
}
.page--author {
  max-width: 1000px;
}
.page--about-gallery {
  max-width: 1000px;
}
.page--contact {
  max-width: 640px;
}
.page--notfound {
  max-width: 640px;
}

.section-title {
  font-size: 15px;
  font-weight: 500;
  letter-spacing: 0.4em;
  text-transform: uppercase;
  color: var(--gold);
  margin: 0 0 8px;
}

.section-sub {
  font-size: 14px;
  font-weight: 300;
  letter-spacing: 0.05em;
  color: var(--muted);
  margin: 0 0 48px;
}

.empty-note {
  font-size: 14px;
  font-weight: 300;
  color: var(--muted);
  letter-spacing: 0.05em;
}

/* ---- Page entrance ------------------------------------------------------- */

/* fadeUp is the site's one entrance gesture — the Domov logo, the gallery
   cards and the text pages all share it, so nothing snaps into place. Only
   the running order differs, and one beat is 120ms everywhere.
   The gallery has to work its order out in JavaScript because only layout
   knows where a masonry card landed; every page below is a fixed structure,
   so its beats are declared here with the rest of the design.
   Neutralised wholesale by the reduced-motion block at the end of the file. */

.page .section-title,
.page .section-sub,
.page .empty-note {
  animation: fadeUp 0.8s ease both;
}
.page .section-sub {
  animation-delay: 120ms;
}
.page .empty-note {
  animation-delay: 240ms;
}

/* O avtorju: the heading leads, then the portrait, then the copy — the same
   running order as O galeriji, and the order the stacked grid reads below 760px. */
.page--author .portrait {
  animation: fadeUp 0.8s ease 120ms both;
}
.page--author .author-text .body-copy {
  animation: fadeUp 0.8s ease 240ms both;
}

/* O galeriji: heading, then the photo, then the copy under it. */
.page--about-gallery .about-gallery-media {
  animation: fadeUp 0.8s ease 120ms both;
}
.page--about-gallery .about-gallery-text .body-copy {
  animation: fadeUp 0.8s ease 240ms both;
}

/* Kontakt: heading, then whichever of photo/text/info are actually present —
   each still one beat (120ms) after the last regardless of what is skipped,
   since :nth-of-type would otherwise stagger differently per work depending
   on what Nastavitve has filled in. */
.page--contact .contact-media {
  animation: fadeUp 0.8s ease 120ms both;
}
.page--contact .body-copy {
  animation: fadeUp 0.8s ease 240ms both;
}
.page--contact .contact-info {
  animation: fadeUp 0.8s ease 360ms both;
}

/* 404: heading, line, then the way back. */
.page--notfound .btn-outline {
  animation: fadeUp 0.8s ease 240ms both;
}

/* ---- Domov --------------------------------------------------------------- */

.home {
  flex: 1;
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 48px;
  padding: 40px;
}
.home-logo {
  width: min(800px, 80vw);
  height: auto;
  display: block;
  animation: fadeUp 0.8s ease both;
}

/* Follows the logo in, a beat later, so the eye lands on the mark first.
   Scoped to .home so it outranks .btn-solid's own align-self, which is
   declared further down the file and would otherwise win on source order. */
.home .home-enter {
  align-self: center;
  animation: fadeUp 0.8s ease 0.35s both;
}

/* ---- Galerija ------------------------------------------------------------ */

.masonry {
  columns: 3 300px;
  column-gap: 32px;
}

/* Each piece fades in like the Domov logo. --reveal-delay is set per card by
   the script at the end of the gallery view, which sorts them by where they
   actually landed so the wave runs across the rows rather than down the
   columns. The 0ms fallback matters: with no JavaScript, or if that script
   never runs, every card simply fades in at once instead of staying hidden.
   Keep animation-delay after the shorthand — the shorthand resets it.
   The 240ms fallback matches the script's BASE, so the no-JS case still lands
   one beat after the heading rather than ahead of the subline above it. */
.artwork {
  margin: 0 0 32px;
  break-inside: avoid;
  display: flex;
  flex-direction: column;
  gap: 12px;
  animation: fadeUp 0.8s ease both;
  animation-delay: var(--reveal-delay, 240ms);
}

.artwork-media {
  display: block;
  width: 100%;
  background-color: var(--surface);
}
.artwork-media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.artwork-caption {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.artwork-title {
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text);
}

/* ---- Lightbox ------------------------------------------------------------ */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: none;
  align-items: flex-start;
  justify-content: center;
  padding: 80px 20px 40px;
  overflow-y: auto;
  overscroll-behavior: contain;
}
.lightbox[hidden] {
  display: none;
}
.lightbox.is-open {
  display: flex;
}

.lightbox-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(10, 10, 10, 0.95);
  animation: fadeIn 0.28s ease both;
}

.lightbox-panel {
  position: relative;
  width: 100%;
  max-width: 1280px;
  background: var(--bg);
  border: 1px solid var(--border);
  padding: 28px;
  animation: lightboxIn 0.38s cubic-bezier(0.22, 0.61, 0.36, 1) both;
}

.lightbox.is-closing .lightbox-backdrop {
  animation: fadeOut 0.22s ease both;
}
.lightbox.is-closing .lightbox-panel {
  animation: lightboxOut 0.22s ease both;
}

.lightbox-close {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 2;
  width: 44px;
  height: 44px;
  background: rgba(10, 10, 10, 0.72);
  border: none;
  cursor: pointer;
  padding: 0;
}
.lightbox-close span {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 18px;
  height: 1px;
  background: var(--text);
  transition: background 0.25s;
}
.lightbox-close span:first-child {
  transform: translate(-50%, -50%) rotate(45deg);
}
.lightbox-close span:last-child {
  transform: translate(-50%, -50%) rotate(-45deg);
}
.lightbox-close:hover span {
  background: var(--gold);
}

/* Image on the left two thirds, everything about the work on the right third. */
.lightbox-body {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: 36px;
  align-items: start;
}

.lightbox-media {
  margin: 0;
}
.lightbox-media img {
  display: block;
  margin: 0 auto;
  max-width: 100%;
  max-height: 78vh;
  width: auto;
  height: auto;
  background: var(--surface);
}

.lightbox-info {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.lightbox-title {
  margin: 0;
  padding-right: 34px; /* clears the close button, which overlaps this corner */
  font-size: 16px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text);
}

.spec {
  margin: 0;
  display: flex;
  flex-direction: column;
}
/* Label above value — the column is a third of the panel, too narrow to hold
   a 190px label and the value on one line. */
.spec > div {
  display: flex;
  flex-direction: column;
  gap: 5px;
  padding: 11px 0;
  border-top: 1px solid var(--hairline);
}
.spec dt {
  font-size: 11px;
  letter-spacing: 0.25em;
  text-transform: uppercase;
  color: var(--muted);
}
.spec dd {
  margin: 0;
  font-size: 14px;
  font-weight: 300;
  letter-spacing: 0.03em;
  color: var(--body);
}

.lightbox-desc .body-copy {
  font-size: 15px;
  margin-bottom: 16px;
}
.lightbox-info .btn-solid {
  align-self: flex-start;
}

/* ---- Buttons ------------------------------------------------------------- */

.btn-outline {
  display: inline-block;
  background: none;
  border: 1px solid var(--gold);
  color: var(--gold);
  font-family: inherit;
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  padding: 8px 14px;
  cursor: pointer;
  white-space: nowrap;
  transition:
    background 0.2s,
    color 0.2s;
}
.btn-outline:hover {
  background: var(--gold);
  color: var(--bg);
}

.btn-solid {
  align-self: flex-start;
  background: var(--gold);
  border: 1px solid var(--gold);
  color: var(--bg);
  font-family: inherit;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.25em;
  text-transform: uppercase;
  padding: 14px 34px;
  cursor: pointer;
  transition:
    background 0.2s,
    color 0.2s;
}
.btn-solid:hover {
  background: transparent;
  color: var(--gold);
}

/* ---- O avtorju ----------------------------------------------------------- */

/* The heading comes first in the markup so it reads first when the grid
   stacks; on wide screens the areas put it back beside the portrait. */
.author-intro {
  display: grid;
  grid-template-columns: minmax(260px, 380px) 1fr;
  grid-template-rows: auto 1fr;
  grid-template-areas:
    "portrait title"
    "portrait text";
  column-gap: 60px;
  row-gap: 24px;
  align-items: start;
}
/* The row gap owns the space under the heading here, not its own margin. */
.author-intro .section-title {
  grid-area: title;
  margin-bottom: 0;
}
.author-intro .portrait {
  grid-area: portrait;
}
.author-intro .author-text {
  grid-area: text;
}

.portrait {
  width: 100%;
}
.portrait img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 7;
  object-fit: cover;
  background: var(--surface);
}
.portrait-placeholder {
  width: 100%;
  aspect-ratio: 4 / 7;
  background: var(--surface);
  border: 1px dashed var(--border);
  display: flex;
  align-items: center;
  justify-content: center;
}
.portrait-placeholder span {
  font-size: 11px;
  letter-spacing: 0.25em;
  text-transform: uppercase;
  color: var(--faint);
}

.body-copy {
  font-size: 16px;
  font-weight: 300;
  line-height: 1.9;
  color: var(--body);
  margin: 0 0 22px;
}
.body-copy:last-child {
  margin-bottom: 0;
}

/* ---- O galeriji ---------------------------------------------------------- */

/* The photo is landscape and runs the full width of the page, with the text
   underneath it. */
.about-gallery-media {
  margin: 0 0 44px;
  background: var(--surface);
}
.about-gallery-media img {
  display: block;
  width: 100%;
  height: auto;
}

.page--about-gallery .section-title {
  margin-bottom: 40px;
}

.about-gallery-text {
  max-width: 760px;
}

/* ---- Kontakt --------------------------------------------------------------- */

.contact-media {
  margin: 0 0 40px;
  background: var(--surface);
}
.contact-media img {
  display: block;
  width: 100%;
  height: auto;
}

/* Label above a value would waste this page's width — 640px is plenty for
   both side by side, unlike the lightbox's narrow third column. */
.contact-info {
  display: flex;
  flex-direction: column;
  gap: 18px;
  margin-top: 28px;
}
.contact-info p {
  margin: 0;
  display: flex;
  align-items: baseline;
  gap: 20px;
}
.contact-info span {
  flex: 0 0 100px;
  font-size: 11px;
  letter-spacing: 0.25em;
  text-transform: uppercase;
  color: var(--muted);
}
.contact-info a {
  font-size: 16px;
  font-weight: 300;
}

/* ---- Footer -------------------------------------------------------------- */

/* Since the Kontakt page went away this is the only place the contact details
   appear, so the footer carries two rows: the details, then the fine print. */
/* One row: the notice at the left edge, the contact details centred, the
   credit at the right. A three-column grid rather than space-between, which
   would centre the middle block only if the two flanking it happened to be
   the same width — they are not, and the contact column changes width with
   whatever is filled in under Nastavitve. */
.site-footer {
  padding: 28px 40px;
  border-top: 1px solid var(--hairline);
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 16px 40px;
}

.footer-copy {
  justify-self: start;
}
.footer-credit {
  justify-self: end;
}
.footer-copy,
.footer-credit {
  font-size: 11px;
  letter-spacing: 0.25em;
  text-transform: uppercase;
  color: var(--faint);

  /* Between roughly 940px and 1120px the three columns want more room than
     there is. Without this the two 1fr columns give first and these break
     mid-phrase; with it the middle column takes the squeeze and wraps its
     own items instead, which is the one of the three that wraps tidily. */
  white-space: nowrap;
}

/* Left in mixed case at a readable size, against the small caps either side:
   an uppercased e-mail address is hard to read back, and these are the one
   part of the footer meant to be used rather than just read. */
.footer-contact {
  justify-self: center;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 4px 32px;
  font-size: 12px;
  font-weight: 300;
  letter-spacing: 0.06em;
}

/* ---- Responsive ---------------------------------------------------------- */

@media (max-width: 760px) {
  .author-intro {
    grid-template-columns: 1fr;
    grid-template-rows: auto;
    grid-template-areas:
      "title"
      "portrait"
      "text";
    row-gap: 32px;
  }
  .portrait {
    max-width: 380px;
  }

  .about-gallery-media {
    margin-bottom: 32px;
  }
}

/* Below this the third column is too narrow to read — stack it under the image. */
@media (max-width: 900px) {
  .lightbox-body {
    grid-template-columns: 1fr;
    gap: 28px;
  }
  .lightbox-media img {
    max-height: 64vh;
  }
}

/* The footer's three columns want roughly 950px between them. Below that they
   stack against the left edge rather than squeezing — centring the middle one
   over two left-aligned rows would read as a mistake. */
@media (max-width: 940px) {
  .site-footer {
    grid-template-columns: 1fr;
    gap: 18px;
  }
  .footer-copy,
  .footer-contact,
  .footer-credit {
    justify-self: start;
  }
  .footer-contact {
    justify-content: flex-start;
  }
}

@media (max-width: 600px) {
  .site-header {
    padding: 18px 20px;
  }
  .wordmark img {
    height: 26px;
  }
  .page {
    padding: 108px 20px 64px;
  }
  .menu-link {
    font-size: 26px;
    padding: 12px 16px;
  }
  .site-footer {
    padding: 28px 20px;
  }
  /* Stacked one per line: side by side they wrap mid-address at this width. */
  .footer-contact {
    flex-direction: column;
    gap: 10px;
  }
  .contact-info p {
    flex-direction: column;
    gap: 4px;
  }
  .home {
    gap: 36px;
  }
  .artwork-caption {
    flex-wrap: wrap;
    gap: 10px;
  }

  .lightbox {
    padding: 70px 14px 24px;
  }
  .lightbox-panel {
    padding: 16px;
  }
  .lightbox-media img {
    max-height: 56vh;
  }
  .lightbox-info {
    gap: 20px;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;

    /* Without this the staggered gallery cards keep their delay while the
       animation itself is gone, so a `both`-filled fadeUp holds them at
       opacity 0 for over a second. !important also beats the inline delay. */
    animation-delay: 0s !important;
  }
}
