/* Workshop / minimal-gallery pass. Replaces the placeholder scaffold styles. */

:root {
  --bg: oklch(98% 0.006 85);
  --fg: oklch(20% 0.008 85);
  --muted: oklch(48% 0.01 85);
  --accent: oklch(55% 0.156 51); /* Goku Orange, darkened for AA text contrast */
  --warn: oklch(50% 0.16 25); /* same L/C formula as --accent, red hue, for form error state */
  --line: oklch(88% 0.01 85);
  --image-outline: #666;
  --quote-bg: oklch(94% 0.02 51); /* light tint, same hue as --accent */
  --max-w: 64rem;
  --gap: 3px;
  --radius: 0px;
  --mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;
  font-family: "IBM Plex Sans", ui-sans-serif, system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
  font-size: 17px;
  line-height: 1.55;
}

/* Category hues (galleries: Fail Whale blue, projects: Pistachio green, blog: Rosewood
   Dreams rust) — same L/C formula as before, hues updated to the new palette (2026-08-18) */
:root {
  --cat-galleries-bg: oklch(93% 0.02 236);
  --cat-galleries-tag: oklch(48% 0.11 236);
  --cat-projects-bg: oklch(93% 0.02 130);
  --cat-projects-tag: oklch(48% 0.11 130);
  --cat-blog-bg: oklch(93% 0.02 32);
  --cat-blog-tag: oklch(48% 0.13 32);
}

* { box-sizing: border-box; }
html { scrollbar-gutter: stable; }
html, body { margin: 0; padding: 0; background: var(--bg); color: var(--fg); }

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

img { max-width: 100%; height: auto; display: block; }
iframe { max-width: 100%; height: auto; display: block; }
figure { margin: 0; }

/* --- header / nav --- */
.site-header {
  display: flex; align-items: baseline; gap: 1.25rem;
  padding: 1rem 1.25rem;
  border-bottom: 1.5px solid var(--fg);
  flex-wrap: wrap;
}
.site-title {
  font-family: var(--mono); font-weight: 400; font-size: 1rem;
  letter-spacing: -0.01em; color: var(--fg);
  display: flex; align-items: center; gap: 0.5rem;
}
.site-title::before {
  content: ""; display: inline-block; width: 9px; height: 9px;
  border: 1.5px solid currentColor; transform: rotate(45deg);
}
.site-title:hover { color: var(--accent); text-decoration: none; }
.site-tagline {
  font-family: var(--mono); font-size: 0.72rem; color: var(--muted); letter-spacing: 0.04em;
}
.site-utility {
  margin-left: auto; display: flex; gap: 1.25rem; align-items: center;
  font-family: var(--mono); font-size: 0.78rem; letter-spacing: 0.03em; text-transform: uppercase;
}
.site-utility a { color: var(--fg); }
.site-utility a:hover { color: var(--accent); text-decoration: none; }

/* --- category sub-nav (tabs, used on home + listing pages) --- */
.subnav {
  display: flex; gap: 0; flex-wrap: wrap;
  padding: 0.6rem 1.25rem;
  margin-bottom: 1rem;
  position: sticky; top: 0;
  background: color-mix(in oklab, var(--bg) 95%, transparent);
  z-index: 5;
  border-bottom: 1px solid var(--line);
  font-family: var(--mono); font-size: 0.75rem; letter-spacing: 0.03em; text-transform: uppercase;
}

/* --- footer --- */
.site-footer {
  padding: 1.25rem; border-top: 1.5px solid var(--fg);
  color: var(--muted); font-size: 0.75rem; margin-top: 4rem;
  font-family: var(--mono);
  display: flex; justify-content: space-between; flex-wrap: wrap; gap: 0.5rem;
}

/* --- main column for prose pages --- */
main { max-width: var(--max-w); margin: 0 auto; padding: 1rem 1.5rem; }
.post { max-width: 38rem; margin: 0 auto; }
.post-title { font-size: 2rem; line-height: 1.15; margin: 0 0 0.25rem; }
.post-meta { color: var(--muted); font-size: 0.9rem; margin: 0 0 2rem; font-family: var(--mono); }
.post-body p { margin: 1rem 0; }
.post-body figure { margin: 1.5rem 0; }
.post-body img { border-radius: var(--radius); }
.post-body h2 { margin-top: 2.5rem; }
.post-body blockquote {
  margin: 2rem 0 2rem 1.5rem;
  padding: 1rem 1.5rem;
  background: var(--quote-bg);
  border-left: 3px solid var(--accent);
  font-size: 1.15em;
  font-style: italic;
  line-height: 1.5;
}
.post-body blockquote p { margin: 0.5rem 0; }
.post-body blockquote p:first-child { margin-top: 0; }
.post-body blockquote p:last-child { margin-bottom: 0; }
.tag { display: inline-block; background: var(--line); border-radius: 2px; padding: 0.05em 0.35em; font-size: 0.85em; color: var(--fg); font-family: var(--mono); }

.post-nav { display: flex; justify-content: space-between; gap: 1rem; margin: 3rem 0 0; padding-top: 1rem; border-top: 1px solid var(--line); font-size: 0.95rem; }
.post-nav-prev { margin-right: auto; }
.post-nav-next { margin-left: auto; }

/* --- listing pages --- */
.listing { max-width: var(--max-w); margin: 0 auto; }
.listing-title { padding: 1.5rem 1.5rem 0; margin: 0; font-size: 1.75rem; font-weight: 600; }
.listing-empty { padding: 2rem 1.5rem; color: var(--muted); font-family: var(--mono); }
.post-list { list-style: none; padding: 0; }
.post-list-item { padding: 0.75rem 0; border-bottom: 1px solid var(--line); }
.post-list-link { font-weight: 500; }
.post-list-date { color: var(--muted); font-size: 0.85rem; margin-left: 0.75rem; font-family: var(--mono); }
.post-list-desc { color: var(--muted); margin: 0.25rem 0 0; font-size: 0.95rem; }

/* --- home grid --- */
.home { padding: 0 0.5rem; }

.filter-chip {
  display: inline-block;
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  padding: 0.3rem 0.1rem;
  margin-right: 1.1rem;
  font: inherit;
  color: var(--muted);
  cursor: pointer;
}
.filter-chip:hover { color: var(--fg); text-decoration: none; }
.filter-chip.is-active { color: var(--fg); border-bottom-color: var(--fg); }

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: var(--gap);
  padding: var(--gap) 0 0;
}
.grid-item {
  position: relative;
  display: block;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--bg);
}
.grid-item.is-hidden { display: none; }
.grid-item[data-category="galleries"] { background: var(--cat-galleries-bg); }
.grid-item[data-category="projects"]  { background: var(--cat-projects-bg); }
.grid-item[data-category="blog"]      { background: var(--cat-blog-bg); }

.js-pagination[hidden] { display: none; }
.grid-item img,
.grid-item picture {
  width: 100%; height: 100%; object-fit: cover; display: block;
}
.grid-item-placeholder {
  display: block; width: 100%; height: 100%;
  background: linear-gradient(135deg, oklch(93% 0.01 85), oklch(88% 0.01 85));
}

/* Category accent bar — thin colour-coded strip along the bottom edge of
   every tile, always visible (unlike the pale --cat-*-bg wash above, which
   never shows once a real photo fills the tile via object-fit: cover).
   This is the primary at-a-glance category signal on mixed-category grids
   (home, search); single-category listing pages don't set data-category,
   so this rule simply doesn't apply there. 2026-08-18. */
.grid-item::after {
  content: "";
  position: absolute; left: 0; right: 0; bottom: 0; height: 4px;
  z-index: 2;
}
.grid-item[data-category="galleries"]::after { background: var(--cat-galleries-tag); }
.grid-item[data-category="projects"]::after  { background: var(--cat-projects-tag); }
.grid-item[data-category="blog"]::after      { background: var(--cat-blog-tag); }

/* Category tag badge — top-right corner, colour-coded per category.
   Nested inside .grid-item-overlay in the markup (both index.njk and
   search.njk) so it inherits the overlay's hover/focus-only opacity —
   with 100+ blog posts, an always-on text badge on every tile was too
   noisy; the always-visible signal is the accent bar above, and this
   text label is a hover-revealed confirmation of the exact category. */
.grid-item-cat {
  position: absolute; top: 6px; right: 6px;
  font-family: var(--mono); font-size: 0.6rem; letter-spacing: 0.05em;
  padding: 1px 5px; color: var(--bg); text-transform: uppercase; z-index: 2;
}
.grid-item[data-category="galleries"] .grid-item-cat { background: var(--cat-galleries-tag); }
.grid-item[data-category="projects"]  .grid-item-cat { background: var(--cat-projects-tag); }
.grid-item[data-category="blog"]      .grid-item-cat { background: var(--cat-blog-tag); }

/* Once the home grid is filtered down to a single category (chip !== "all"),
   the accent bar and badge stop being informative — every visible tile is
   the same colour/label. `applyFilter()` in index.njk toggles this class on
   #home-grid; hide both category signals so filtered views match the plain
   title + date treatment the dedicated listing pages already use. 2026-08-18. */
.grid.is-single-category .grid-item::after,
.grid.is-single-category .grid-item-cat {
  display: none;
}

.grid-item-overlay {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; justify-content: flex-end;
  padding: 0.65rem;
  background: linear-gradient(to top, oklch(20% 0.008 85 / 0.82) 0%, transparent 55%);
  opacity: 0;
  transition: opacity 0.15s ease-out;
}
.grid-item:hover .grid-item-overlay,
.grid-item:focus-visible .grid-item-overlay {
  opacity: 1;
}
.grid-item-title { font-weight: 500; line-height: 1.2; }
.grid-item-meta { display: flex; gap: 0.5rem; font-size: 0.68rem; font-family: var(--mono); opacity: 0.85; margin-top: 0.25rem; }
.grid-item-cat-inline { display: none; } /* superseded by .grid-item-cat badge */

@media (hover: none) {
  .grid-item-overlay { opacity: 1; }
}

/* --- pagination --- */
.pagination {
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
  margin: 2rem auto 0;
  padding: 1.1rem 1rem 0;
  justify-content: center;
  border-top: 1px solid var(--line);
  font-family: var(--mono);
}
.pagination-link {
  color: var(--muted);
  font-size: 0.78rem;
  padding: 0.3rem 0.6rem;
  text-decoration: none;
}
.pagination-link:hover { color: var(--accent); text-decoration: none; }
.pagination-link.is-disabled { opacity: 0.35; cursor: default; }
.pagination-pages {
  display: flex;
  list-style: none;
  padding: 0;
  margin: 0;
  gap: 0.4rem;
}
.pagination-num {
  display: inline-block;
  min-width: 1.6rem;
  padding: 0.15rem 0.4rem;
  text-align: center;
  font-size: 0.78rem;
  color: var(--muted);
  text-decoration: none;
  border-radius: var(--radius);
}
.pagination-num:hover { color: var(--fg); text-decoration: none; }
.pagination-num.is-active {
  color: var(--bg);
  background: var(--fg);
}

/* --- search toggle + bar --- */
.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;
}

.search-toggle {
  background: none;
  border: 1px solid var(--fg);
  border-radius: 0;
  width: 26px; height: 26px;
  padding: 0;
  margin-left: 0.25rem;
  cursor: pointer;
  color: var(--fg);
  display: flex;
  align-items: center;
  justify-content: center;
}
.search-toggle:hover { color: var(--accent); border-color: var(--accent); }
.search-toggle[aria-expanded="true"] { color: var(--fg); }

.search-bar {
  border-bottom: 1px solid var(--line);
  background: var(--bg);
}
.search-form {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  max-width: 100rem;
  margin: 0 auto;
  padding: 0.65rem 1.5rem;
}
.search-input {
  flex: 1;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 0.45rem 0.75rem;
  font: inherit;
  font-size: 1rem;
  background: var(--bg);
  color: var(--fg);
  -webkit-appearance: none;
}
.search-input:focus {
  outline: 2px solid var(--accent);
  outline-offset: -1px;
  border-color: transparent;
}
.search-input::-webkit-search-cancel-button { display: none; }

.search-submit,
.search-close {
  background: none;
  border: none;
  padding: 0.4rem;
  cursor: pointer;
  color: var(--muted);
  display: flex;
  align-items: center;
}
.search-submit:hover,
.search-close:hover { color: var(--accent); }

/* --- search results page --- */
.search-status {
  text-align: center;
  color: var(--muted);
  font-size: 0.95rem;
  padding: 3rem 1.5rem;
  margin: 0;
}

/* --- gallery page (post-detail) --- */
.gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--gap);
  margin: 2rem 0;
}
.gallery-item { margin: 0; }
.gallery-item img { border-radius: var(--radius); }
.gallery-item figcaption {
  font-size: 0.85rem; color: var(--muted); margin-top: 0.25rem;
}

/* --- lightbox gallery grid ({% gallery %} shortcode) --- */
.lb-gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: var(--gap);
  margin: 2rem 0;
}
.lb-gallery a.pswp-item {
  display: block;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  border-radius: var(--radius);
  background: var(--line);
  cursor: zoom-in;
}
.lb-gallery a.pswp-item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.lb-gallery-figure {
  margin: 2rem 0;
}
.lb-gallery-figure .lb-gallery {
  margin: 0;
}

/* --- standalone lightbox image ({% lbImage %} shortcode) --- */
.pswp-solo {
  margin: 1.5rem 0;
}
.pswp-solo a.pswp-item {
  display: block;
  cursor: zoom-in;
}
.pswp-solo a.pswp-item picture,
.pswp-solo a.pswp-item img {
  display: block;
  border-radius: var(--radius);
  outline: 1px solid var(--image-outline);
}

/* --- chained inline image ({% postImg %} shortcode) --- */
/* `.postimg-item` is a CSS-only hook alongside `.pswp-item`, so this doesn't
   pick up gallery thumbnails (those use plain `.pswp-item` inside `.lb-gallery`). */
.postimg-item picture,
.postimg-item img {
  outline: 1px solid var(--image-outline);
}

/* --- plain inline image ({% image %} shortcode) --- */
/* Not applied to `{% gridImage %}` thumbnails (home/listing grid). */
.img-outlined,
.img-outlined img {
  outline: 1px solid var(--image-outline);
}

/* --- captions --- */
.post-body figure figcaption,
.pswp-solo figcaption,
.lb-gallery-figure figcaption {
  margin-top: 0.35rem;
  font-style: italic;
  font-size: 0.9em;
  line-height: 1.4;
  color: var(--muted);
}


/* --- contact form --- */
.contact-form { max-width: 30rem; margin: 1.5rem 0 0; }
.contact-form__field {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  margin: 0 0 1.1rem;
}
.contact-form__field label { font-weight: 500; }
.contact-form__optional { font-weight: 400; color: var(--muted); font-size: 0.85em; }

.contact-form input[type="text"],
.contact-form input[type="email"],
.contact-form textarea {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 0.55rem 0.7rem;
  font: inherit;
  font-size: 1rem;
  background: var(--bg);
  color: var(--fg);
  width: 100%;
}
.contact-form input:focus,
.contact-form textarea:focus {
  outline: 2px solid var(--accent);
  outline-offset: -1px;
  border-color: transparent;
}
.contact-form textarea { resize: vertical; min-height: 8rem; }

/* Honeypot field — off-screen, not display:none (some spam bots
   specifically skip display:none fields since it's the most common
   honeypot pattern). */
.contact-form__hp { position: absolute; left: -9999px; top: -9999px; }

/* Shared button style — mono/uppercase, matches the site's bordered,
   sharp-cornered, hover-to-accent language used elsewhere (search
   toggle, filter chips). */
.button {
  display: inline-block;
  border: 1.5px solid var(--fg);
  background: var(--fg);
  color: var(--bg);
  font-family: var(--mono);
  font-size: 0.8rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 0.65rem 1.5rem;
  cursor: pointer;
  border-radius: var(--radius);
}
.button:hover { background: var(--accent); border-color: var(--accent); text-decoration: none; }

/* Post-submit status message — shown/hidden by inline JS on contact.njk
   reading ?sent=1 / ?error=1 off the redirect from contact-handler.php
   (same "read the URL, toggle a class" approach as the home grid filter). */
.contact-form-status {
  max-width: 30rem;
  margin: 1.5rem 0;
  padding: 0.75rem 1rem;
  font-family: var(--mono);
  font-size: 0.85rem;
  border: 1px solid var(--line);
}
.contact-form-status.is-success { border-color: var(--cat-projects-tag); color: var(--cat-projects-tag); }
.contact-form-status.is-error { border-color: var(--warn); color: var(--warn); }
