/* ==========================================================================
   Portfolio Theme — theme.css
   Production dark OKLCH theme for portfolio-site-generator.
   MUST NOT contain hex, legacy rgb, or legacy hsl colour values (FR-006).
   MUST NOT contain <script> content (FR-034).
   ========================================================================== */

/* Section 1 — @font-face declarations (FR-008, CL-011)
   ========================================================================== */

@font-face {
  font-family: 'Playfair Display';
  src: url('../fonts/PlayfairDisplay-variable.woff2') format('woff2-variations');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Outfit';
  src: url('../fonts/Outfit-variable.woff2') format('woff2-variations');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* Section 2 — :root design tokens (FR-004, FR-005, FR-007, FR-009, FR-010)
   ========================================================================== */

:root {
  font-size: 17px;         /* sets rem baseline — only px font-size permitted */
  --font-display:  2.71rem;
  --font-heading:  1.53rem;
  --font-body:     1rem;
  --font-caption:  0.88rem;
  --font-label:    0.59rem;
  --font-meta:     0.71rem;
  --space-xs: 0.47rem;
  --space-sm: 1rem;
  --space-md: 1.41rem;
  --space-lg: 2.82rem;
  --space-xl: 4.24rem;
  /* Colours — OKLCH only, no hex/rgb/hsl (FR-006) */
  --surface-base:  oklch(0.12 0 0);
  --surface-mat:   oklch(0.30 0 0);
  --text-primary:  oklch(0.88 0 0);
  --text-muted:    oklch(0.60 0 0);   /* CL-009: confirmed ~5.2:1 */
  --text-subtle:   oklch(0.58 0 0);   /* CL-009: confirmed ~4.7:1 */
  --text-dim:      oklch(0.68 0 0);
  --accent:        oklch(0.60 0.08 200);
  --border-strong: oklch(0.22 0 0);
  --border-subtle: oklch(0.18 0 0);
}

/* Section 3 — Wide-gamut P3 accent override (FR-005)
   ========================================================================== */

@media (color-gamut: p3) {
  :root {
    --accent: oklch(0.60 0.13 200);
  }
}

/* Section 4 — Box-sizing reset and body defaults
   ========================================================================== */

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

body {
  margin: 0;
  background: var(--surface-base);
  color: var(--text-primary);
  font-family: 'Outfit', sans-serif;
  font-size: var(--font-body);
  line-height: 1.6;
  /* Anchor footer to viewport bottom on sparse pages */
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}

body > main {
  flex: 1 0 auto;
}

/* Section 5 — Focus-visible ring (FR-029, CL-010)
   ========================================================================== */

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

/* Section 6 — Sticky header (FR-015, US5)
   ========================================================================== */

.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--space-xs) var(--space-md);
  background: var(--surface-base);
  border-bottom: 1px solid var(--border-strong);
}

.site-name {
  font-family: 'Outfit', sans-serif;
  font-size: var(--font-label);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--text-primary);
  text-decoration: none;
}

.site-header nav ul {
  display: flex;
  gap: var(--space-sm);
  list-style: none;
  margin: 0;
  padding: 0;
}

.site-header nav a {
  font-family: 'Outfit', sans-serif;
  font-size: var(--font-label);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--text-muted);
  text-decoration: none;
}

.site-header nav a:hover {
  color: var(--text-primary);
}

[aria-current="page"] {
  color: var(--accent);
}

/* Section 7 — Footer (FR-022, US5)
   ========================================================================== */

.site-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--space-sm) var(--space-md);
  font-family: 'Outfit', sans-serif;
  font-size: var(--font-label);
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: var(--text-subtle);
  border-top: 1px solid var(--border-subtle);
  margin-top: var(--space-lg);
}

/* Section 8 — Gallery grid — CSS columns masonry (FR-012, FR-013, FR-014, US2)
   ========================================================================== */

.gallery-grid {
  columns: 2;
  column-gap: var(--space-sm);
  list-style: none;
  margin: 0;
  padding: 0;
}

.gallery-grid .thumb {
  break-inside: avoid;
  margin-bottom: var(--space-sm);
  border-radius: 2px;
  overflow: hidden;
  display: block;
  width: 100%;
}

.gallery-grid .thumb img {
  display: block;
  width: 100%;
  height: auto;
}

@media (max-width: 40em) {
  .gallery-grid { columns: 1; }
}

/* Section 9 — Gallery index (FR-017, US2 scenario 3)
   ========================================================================== */

.gallery-index {
  padding: var(--space-md);
}

.gallery-index h1 {
  font-family: 'Playfair Display', serif;
  font-size: var(--font-display);
  font-weight: 700;
  color: var(--text-primary);
  margin-bottom: var(--space-lg);
}

.gallery-index .gallery-title {
  display: flex;
  flex-direction: column;
  font-family: 'Playfair Display', serif;
  font-size: var(--font-display);
  color: var(--text-primary);
}

/* T010 (041 FR-001..FR-004): gallery card overlay — position cover img and title overlay
   so the title sits in the lower region over a transparent-to-dark OKLCH gradient scrim.
   Always visible (no hover gate) per FR-003/FR-026/NFR-004. */

.gallery-index nav a {
  position: relative;
  display: block;
  overflow: hidden;
  border-radius: 2px;
}

.gallery-index nav a .gallery-title-overlay {
  display: block;
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  padding: var(--space-sm) var(--space-xs);
  /* OKLCH gradient scrim: transparent at top → opaque-dark at bottom (~0.78 alpha).
     Text contrast over scrim: white on near-black ≥4.5:1 (FR-002/NFR-003). */
  background: linear-gradient(to top, oklch(0.06 0 0 / 0.82), oklch(0.06 0 0 / 0));
  color: var(--text-primary);
  font-family: 'Playfair Display', serif;
  font-size: var(--font-body);
  font-weight: 600;
  line-height: 1.2;
  /* Ensure the title wraps rather than overflows (FR-003 edge case: long titles) */
  word-break: break-word;
}

/* FR-004: cover-less card — title is legible on --surface-base without a scrim.
   When no <img> is present the anchor has no cover; the title renders as plain
   block text on the dark surface background. No additional treatment needed since
   --text-primary on --surface-base already exceeds 4.5:1. */
.gallery-index nav a:not(:has(img)) .gallery-title-overlay {
  position: static;
  background: none;
  padding: 0;
}

/* FR-004: @supports fallback for browsers that do not support :has() (pre-Firefox 121,
   pre-Chrome 105). Without this, the .gallery-title-overlay stays position:absolute in a
   zero-height ancestor on cover-less cards, making the title invisible. */
@supports not selector(:has(*)) {
  .gallery-index nav a .gallery-title-overlay {
    position: static;
    background: none;
  }
}

.gallery-index nav ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(20rem, 28rem));
  justify-content: center;
  gap: var(--space-lg);
}

.gallery-index nav li {
  display: flex;
  flex-direction: column;
}

.gallery-index nav a {
  font-family: 'Playfair Display', serif;
  font-size: var(--font-display);
  color: var(--text-primary);
  text-decoration: none;
}

.gallery-index nav a:hover {
  color: var(--accent);
}

.gallery-index nav img {
  display: block;
  width: 100%;
  height: auto;
  margin-bottom: 0;
  border-radius: 2px;
}

.gallery-index .gallery-title,
.gallery-index nav a {
  line-height: 1.2;
}

/* Section 10 — Image detail layout (FR-018, FR-018a, US3)
   ========================================================================== */

.image-detail {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  padding: var(--space-md);
  align-items: center;
}

.image-mat {
  background: var(--surface-mat);
  padding: clamp(var(--space-sm), 4vw, var(--space-lg));
  border-radius: 2px;
  /* Shrink-wrap to the image so the mat stays a proportional frame */
  width: fit-content;
  max-width: 100%;
}

.image-mat figure {
  margin: 0;
  padding: 0;
}

.image-mat img {
  display: block;
  width: auto;
  height: auto;
  max-width: 100%;
  /* Cap height so a landscape image fits the viewport without scrolling */
  max-height: calc(100dvh - 14rem);
}

/* Section 11 — Metadata panel (FR-019, US3 scenario 6)
   ========================================================================== */

.meta-panel {
  max-width: 65ch;
  width: 100%;
}

.image-title {
  font-family: 'Playfair Display', serif;
  font-size: var(--font-heading);
  font-weight: 700;
  color: var(--text-primary);
  margin-top: 0;
  margin-bottom: var(--space-sm);
  padding: 0 var(--space-md);
}

.meta-panel .image-caption {
  font-family: 'Playfair Display', serif;
  font-size: var(--font-body);
  font-style: normal;
  color: var(--text-dim);
  margin-bottom: var(--space-sm);
}

.meta-panel dl.exif {
  margin: 0;
  padding: 0;
}

.meta-panel dl.exif dt {
  font-family: 'Outfit', sans-serif;
  font-size: var(--font-caption);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--text-subtle);
  padding-top: var(--space-xs);
  margin-top: 0;
  border-bottom: 1px solid var(--border-subtle);
}

.meta-panel dl.exif dd {
  font-family: 'Outfit', sans-serif;
  font-size: var(--font-caption);
  font-weight: 400;
  color: var(--text-dim);
  margin: 0;
  padding-bottom: var(--space-xs);
  border-bottom: 1px solid var(--border-subtle);
}

/* T022 (041 FR-012/FR-013): two-column EXIF metadata at wide viewports.
   Each dt+dd pair sits in a single grid row; collapses to one column at the
   mobile breakpoint. The panel remains below the image at all widths
   (flex-direction: column on .image-detail preserves FR-013). */

.meta-panel dl.exif {
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: var(--space-sm);
}

.meta-panel dl.exif dt {
  grid-column: 1;
}

.meta-panel dl.exif dd {
  grid-column: 2;
}

@media (max-width: 40em) {
  .meta-panel dl.exif {
    display: block;
  }
}

/* Section 12 — Prev/next navigation (FR-020, US3 scenarios 8-11)
   ========================================================================== */

/* T025 (041 FR-006/FR-007): image-nav row frames the panel beneath the photo.
   prev link (left) / position counter (centre) / next link (right). */

.image-nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--space-sm) var(--space-md);
  border-top: 1px solid var(--border-subtle);
  width: 100%;
  max-width: 65ch;
}

.image-nav a {
  font-family: 'Outfit', sans-serif;
  font-size: var(--font-label);
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--accent);
  text-decoration: none;
  transition: color 0.15s ease;
}

.image-nav a:hover {
  color: var(--text-primary);
}

/* T025 (041 FR-016): non-anchor position counter centred in the nav row. */
.image-position {
  font-family: 'Outfit', sans-serif;
  font-size: var(--font-meta);
  color: var(--text-subtle);
  letter-spacing: 0.1em;
  text-align: center;
  flex: 1;
}

/* T025 (041 FR-008/FR-009): panel-license — prominent labelled licence item inside meta-panel. */
.panel-license {
  font-family: 'Outfit', sans-serif;
  font-size: var(--font-caption);
  color: var(--text-dim);
  margin-top: 0;
  margin-bottom: var(--space-sm);
  font-weight: 500;
}

.panel-license a {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-color: var(--accent);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

/* T025 (041 FR-017/FR-018): license-notice link inside site-footer. */
.license-notice a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* Section 13 — Static page body (FR-021, US4)
   ========================================================================== */

.page-body {
  max-width: 65ch;
  margin: 0 auto;
  padding: var(--space-md);
  font-family: 'Outfit', sans-serif;
  font-weight: 300;
  font-size: var(--font-body);
  color: var(--text-muted);
  line-height: 1.85;
}

.page-body h1 {
  font-family: 'Playfair Display', serif;
  font-size: var(--font-display);
  font-weight: 700;
  color: var(--text-primary);
  margin-bottom: var(--space-md);
}

.page-body h2,
.page-body h3,
.page-body h4 {
  font-family: 'Playfair Display', serif;
  color: var(--text-primary);
  margin-top: var(--space-lg);
  margin-bottom: var(--space-sm);
}

.page-body p {
  margin-bottom: var(--space-sm);
}

.page-body a {
  color: var(--accent);
  text-decoration: underline;
  text-decoration-color: var(--accent);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

/* Section 14 — Breadcrumb nav (CL-007)
   ========================================================================== */

.breadcrumb {
  padding: var(--space-xs) var(--space-md);
  font-family: 'Outfit', sans-serif;
  font-size: var(--font-caption);
}

.breadcrumb a {
  color: var(--text-subtle);
  font-family: 'Outfit', sans-serif;
  font-size: var(--font-caption);
  text-decoration: none;
  /* Transition on the base selector so prefers-reduced-motion (same specificity) wins. */
  transition: color 0.15s ease;
}

/* T023 (041 FR-019): breadcrumb hover → accent colour (supersedes prior text-primary hover). */
.breadcrumb a:hover {
  color: var(--accent);
}

/* Section 15 — Link defaults
   ========================================================================== */

a {
  color: var(--accent);
}

nav a {
  text-decoration: none;
}

/* Gallery description
   ========================================================================== */

.gallery-description {
  font-family: 'Outfit', sans-serif;
  font-size: var(--font-body);
  font-weight: 300;
  color: var(--text-muted);
  max-width: 65ch;
  margin-bottom: var(--space-md);
}

/* 042: inter-paragraph spacing inside Markdown-rendered caption/description */
.meta-panel .image-caption p,
.gallery-description p {
  margin: 0 0 var(--space-xs) 0;
}
.meta-panel .image-caption p:last-child,
.gallery-description p:last-child {
  margin-bottom: 0;
}

/* Gallery page layout
   ========================================================================== */

.gallery-page {
  padding: var(--space-md);
}

/* Breadcrumb has its own horizontal padding for use outside a padded
   wrapper (image detail pages). Inside .gallery-page the wrapper already
   pads, so zero the breadcrumb's horizontal padding to avoid doubling. */
.gallery-page .breadcrumb {
  padding-left: 0;
  padding-right: 0;
}

.gallery-page h1 {
  font-family: 'Playfair Display', serif;
  font-size: var(--font-display);
  color: var(--text-primary);
  margin-bottom: var(--space-sm);
}

/* Tags
   ========================================================================== */

.tags {
  font-family: 'Outfit', sans-serif;
  font-size: var(--font-meta);
  color: var(--text-muted);
  margin-bottom: var(--space-sm);
}

/* Sub-gallery section
   ========================================================================== */

.sub-galleries {
  margin-bottom: var(--space-lg);
}

.sub-galleries h2 {
  font-family: 'Playfair Display', serif;
  font-size: var(--font-heading);
  color: var(--text-primary);
  margin-bottom: var(--space-sm);
}

.sub-galleries ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
}

.sub-galleries a {
  font-family: 'Outfit', sans-serif;
  font-size: var(--font-body);
  color: var(--accent);
  text-decoration: none;
}

/* T023 (041 FR-020/NFR-005): suppress all hover transitions for visitors who
   have expressed a prefers-reduced-motion preference. Applies to breadcrumb,
   image-nav, and any other transition introduced in this feature. */

@media (prefers-reduced-motion: reduce) {
  .breadcrumb a,
  .image-nav a {
    transition: none;
  }
}
