/*
Theme Name: Ogbonna
Theme URI: https://bradogbonna.com
Author: Brad Ogbonna
Description: Minimal image-forward portfolio theme. Full-bleed slideshow home, click-through project viewers, a Motion section, and a per-section thumbnail index.
Version: 3.8
Requires at least: 6.0
Tested up to: 6.6
Requires PHP: 7.4
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: ogbonna
*/

/* ============================================================
   TOKENS — the only numbers you should need to change
   ============================================================ */

:root {
  --bg:   #FFFFFF;
  --ink:  #111111;
  --mute: #999999;
  --hair: #E5E5E5;

  --accent: #D8321E;    /* the red slash in Prev / Next — the only colour */

  --nav-h: 56px;        /* top nav height */

  /* Bottom-left navigation — two lines in the site's own type. The bar
     grows to fit them, and every image sizes itself around that. */
  --bar-size: 12px;
  --bar-gap: 8px;       /* space between PREV / NEXT and SHOW THUMBNAILS */
  --bar-pad-b: 20px;    /* space below the bottom line */
  --bar-h: calc(var(--bar-size) * 2 + var(--bar-gap) + var(--bar-pad-b) + 14px);
  --sidebar-w: 210px;   /* project sidebar */

  /* Image scale — the white border around every frame.
     --slide-x is the margin left and right, --slide-y top and bottom.
     Both apply to portrait and landscape alike, so a tall frame sits
     inside the same border as a wide one. Lower them for bigger
     images, raise them for more white. */
  --slide-x: 3vw;
  --slide-y: 3vh;

  /* Height of the band reserved for a caption, directly above the
     prev/next bar. The photo stops short of it, so a caption never
     sits over the picture. */
  --cap-h: 22px;

  /* Thumbnail sheet. --sheet-h is the height every thumbnail stands at,
     regardless of whether it's a vertical or a horizontal. Widths follow
     from each image's shape. */
  --sheet-gap-x: 14px;
  --sheet-gap-y: 14px;
  --sheet-h: 290px;

  /* Width of the photo on the Info page. */
  --info-img-w: 220px;

  --pad: 22px;
}

/* ============================================================
   RESET
   ============================================================ */

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

html, body { margin: 0; padding: 0; }

body {
  background: var(--bg);
  color: var(--ink);
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
  font-size: 12px;
  line-height: 1.45;
  letter-spacing: 0.01em;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

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

a { color: inherit; text-decoration: none; }

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}

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

.screen-reader-text {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip: rect(1px, 1px, 1px, 1px);
  white-space: nowrap;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 999;
  background: var(--bg);
  padding: 10px 14px;
}
.skip-link:focus { left: 0; }

/* ============================================================
   TOP NAV
   ============================================================ */

.nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 60;
  height: var(--nav-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 var(--pad);
  background: var(--bg);
}

/* Over a full-bleed image the nav inverts against whatever is behind it. */
.nav.over {
  background: transparent;
  mix-blend-mode: difference;
  color: #FFFFFF;
}

.wordmark {
  font-weight: 500;
  letter-spacing: 0.02em;
}

.nav-right {
  display: flex;
  align-items: center;
  gap: 20px;
}

.nav-right a[aria-current="page"],
.nav-right .work[aria-current="true"] { text-decoration: underline; text-underline-offset: 3px; }

/* Work dropdown */
.work { position: relative; cursor: default; }

.work-list {
  position: absolute;
  top: 100%;
  left: 0;
  display: none;
  flex-direction: column;
  gap: 6px;
  padding: 10px 0 0;
  white-space: nowrap;
}
.work:hover .work-list,
.work:focus .work-list,
.work:focus-within .work-list { display: flex; }

.menu-btn { display: none; }

/* ============================================================
   VIEWER — one image at a time, used by home, projects, motion
   ============================================================ */

.viewer {
  position: relative;
  height: calc(100vh - var(--nav-h) - var(--bar-h));
  height: calc(100svh - var(--nav-h) - var(--bar-h));
  margin-top: var(--nav-h);
  overflow: hidden;
}

.slide {
  position: absolute;
  inset: 0;
  display: none;
  align-items: center;
  justify-content: center;
  padding: var(--slide-y) var(--slide-x) calc(var(--slide-y) + var(--cap-h));
}
.slide.on { display: flex; }

/* Portrait: as tall as the stage allows, minus the border. */
.slide.is-portrait img {
  height: 100%;
  width: auto;
  max-width: 100%;
  object-fit: contain;
}

/* Landscape: as wide as the stage allows, minus the border, and
   capped by the height so a very wide frame gains side margin rather
   than losing its top and bottom. */
.slide.is-landscape img,
.slide.is-square img {
  width: auto;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

/* Horizontal placement. Each image gets one of these, so paging through
   shifts the eye rather than dropping every picture in the same spot.
   These only bite when the image is narrower than the frame — a
   landscape already filling the width has no room to move. */
.slide.pos-left   { justify-content: flex-start; }
.slide.pos-center { justify-content: center; }
.slide.pos-right  { justify-content: flex-end; }

/* To switch this off and centre everything, delete the three rules
   above — the default is already centred. */

/* Caption — the attachment's Caption field, in its own band directly
   above the prev/next bar. Set in the same black as the rest of the
   type. Doesn't intercept clicks, so the left/right advance zones still
   work underneath it. */
.slide-caption {
  position: absolute;
  left: var(--slide-x);
  right: var(--slide-x);
  bottom: var(--slide-y);
  z-index: 6;
  margin: 0;
  line-height: var(--cap-h);
  text-align: center;
  color: var(--ink);
  pointer-events: none;
}

.viewer.full .slide-caption {
  bottom: calc(var(--bar-h) + var(--slide-y));
}

/* Follow the photo. A caption stranded in the middle of the page while
   the picture sits far left reads as unrelated to it. */
.slide.pos-left  .slide-caption { text-align: left; }
.slide.pos-right .slide-caption { text-align: right; }

/* Click zones — right half forward, left half back. */
.zone {
  position: absolute;
  top: 0; bottom: 0;
  width: 50%;
  z-index: 5;
  background: transparent;
}
.zone.prev { left: 0;  cursor: w-resize; }
.zone.next { right: 0; cursor: e-resize; }

/* These are mouse conveniences layered over the image, each a half-width
   box taller than the window. A focus ring on one drew its inner edge as
   a hairline straight down the middle of the page. They're out of the tab
   order now — keyboard users get Prev and Next in the bar, which show
   focus properly — and this makes sure no ring can appear on them. */
.zone:focus,
.zone:focus-visible { outline: none; }

/* Home slideshow runs the full height of the window. The nav and the
   bar float over it, so the image still sits inside the same border
   as everywhere else. */
.viewer.full {
  height: 100vh;
  height: 100svh;
  margin-top: 0;
}

/* The nav and bar float over the home slideshow rather than sitting
   above and below it, so the border has to clear them by hand. */
.viewer.full .slide {
  padding:
    calc(var(--nav-h) + var(--slide-y))
    var(--slide-x)
    calc(var(--bar-h) + var(--slide-y) + var(--cap-h));
}

/* ============================================================
   PREV / NEXT / INDEX BAR — the same on every section
   ============================================================ */

/* Two lines, bottom left, in capitals:

     PREV / NEXT
     SHOW THUMBNAILS

   The slash is the only colour on the page. Sits above the thumbnail
   sheet, so the same button reads "Hide thumbnails" and closes it. */
.bar {
  position: fixed;
  bottom: 0; left: 0; right: 0;
  z-index: 90;
  height: var(--bar-h);
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  padding: 0 var(--pad) var(--bar-pad-b);
  background: var(--bg);
}

.bar-nav {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--bar-gap);
  font-size: var(--bar-size);
  line-height: 1;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.bar-step { white-space: nowrap; }
.bar-step a { color: var(--ink); }
.bar-slash  { color: var(--accent); }

.bar-index { color: var(--ink); text-transform: uppercase; }

.bar-nav a:hover,
.bar-index:hover { opacity: 0.55; }

.bar button[disabled],
.bar a[aria-disabled="true"] {
  color: var(--mute);
  cursor: default;
  pointer-events: none;
}

.bar-meta {
  color: var(--mute);
  display: flex;
  align-items: center;
  gap: 14px;
}

.bar-title { color: var(--ink); }

/* On project pages the bar clears the sidebar. */
.has-sidebar .bar { left: var(--sidebar-w); }

/* On the home page the bar floats over the slideshow's white margin.
   The image stops short of it, so no blend trick is needed — and the
   red slash stays red. */
.bar.over { background: transparent; }

/* ============================================================
   INDEX SHEET — the thumbnail overlay, one per section
   ============================================================ */

.sheet {
  position: fixed;
  inset: 0;
  z-index: 80;
  background: var(--bg);
  overflow-y: auto;
  padding: calc(var(--nav-h) + 12px) var(--pad) calc(var(--bar-h) + 32px);
  display: none;
}
.sheet.open { display: block; }

.sheet-head {
  position: sticky;
  top: 0;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding-bottom: 14px;
  background: var(--bg);
}

/* Rows of uniform height rather than columns of uniform width. Every
   thumbnail stands the same height and takes whatever width its shape
   needs, so a vertical reads as narrow and a horizontal as wide, and
   the two can be compared at a glance. --sheet-h is the single number
   to change; the rows reflow around it. */
.sheet-grid {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sheet-gap-y) var(--sheet-gap-x);
  align-items: flex-start;
}

.sheet-item {
  display: block;
  width: auto;
  text-align: left;
}
.sheet-item img {
  height: var(--sheet-h);
  width: auto;
  max-width: none;
}
.sheet-item.is-current img { outline: 1px solid var(--ink); outline-offset: 3px; }

.sheet-cap {
  display: block;
  padding-top: 6px;
  color: var(--mute);
}

/* Motion posters stand the same height as everything else, with 16:9
   fixing their width. */
.sheet-item.motion .poster {
  position: relative;
  display: block;
  height: var(--sheet-h);
  aspect-ratio: 16 / 9;
  background: #EEEEEE;
  overflow: hidden;
}
.sheet-item.motion .poster img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ============================================================
   SELECT WORK — the landing grid
   ============================================================ */

.work-grid {
  margin-top: var(--nav-h);
  padding: 24px var(--pad) 80px;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 28px;
}

.work-card { position: relative; display: block; }
.work-card img { width: 100%; height: auto; }

.work-card .cap {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: 14px 16px;
  color: #FFFFFF;
  font-weight: 700;
  opacity: 0;
  background: linear-gradient(to top, rgba(0,0,0,0.45), rgba(0,0,0,0));
  transition: opacity 120ms linear;
}
.work-card:hover .cap,
.work-card:focus-visible .cap { opacity: 1; }

/* ============================================================
   PROJECT PAGES — persistent sidebar + viewer
   ============================================================ */

.project-shell {
  display: grid;
  grid-template-columns: var(--sidebar-w) 1fr;
  min-height: 100vh;
}

.sidebar {
  position: fixed;
  top: var(--nav-h);
  bottom: var(--bar-h);
  left: 0;
  width: var(--sidebar-w);
  padding: 8px var(--pad) 20px;
  overflow-y: auto;
}

.sidebar ul { list-style: none; margin: 0; padding: 0; }
.sidebar li { padding: 3px 0; }
.sidebar a[aria-current="page"] { text-decoration: underline; text-underline-offset: 3px; }
.sidebar .group {
  color: var(--mute);
  padding: 16px 0 4px;
}
.sidebar .group:first-child { padding-top: 0; }

.project-main { grid-column: 2; }

/* ============================================================
   MOTION
   ============================================================ */

.motion-frame {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 var(--slide-x);
}

.motion-embed {
  width: 100%;
  max-width: calc((100vh - var(--nav-h) - var(--bar-h)) * 16 / 9);
  aspect-ratio: 16 / 9;
  background: #000000;
}
.motion-embed iframe,
.motion-embed video {
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}

/* A URL pasted into the editor body arrives wrapped in WordPress's own
   embed markup, which brings its own aspect-ratio boxes and margins.
   Flatten those so the player fills the frame either way. */
.motion-embed figure,
.motion-embed .wp-block-embed,
.motion-embed .wp-block-embed__wrapper,
.motion-embed p {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
}
.motion-embed .wp-block-embed__wrapper::before { display: none; }

.motion-empty {
  color: var(--mute);
  text-align: center;
  padding: 40px var(--pad);
}

/* Motion landing grid */
.motion-grid {
  margin-top: var(--nav-h);
  padding: 24px var(--pad) 80px;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 28px;
}
.motion-grid .poster {
  position: relative;
  aspect-ratio: 16 / 9;
  background: #EEEEEE;
  overflow: hidden;
}
.motion-grid .poster img { width: 100%; height: 100%; object-fit: cover; }
.motion-grid .cap { padding-top: 8px; }
.motion-grid .client { color: var(--mute); }

/* ============================================================
   INFO
   ============================================================ */

.info-doc {
  margin-top: var(--nav-h);
  padding: 28px var(--pad) 80px;
  max-width: none;
}

/* Four columns at 3 / 2 / 2 / 2. The bio column being half again as
   wide as the others is what stops the page reading as a table — the
   short bio leaves a deep well of white before the client list starts.
   Core Columns block does the layout so the page stays editable. */
.info-doc .wp-block-columns {
  display: flex;
  flex-wrap: nowrap;
  align-items: flex-start;
  gap: 12px;
  margin: 0;
}
.info-doc .wp-block-column { min-width: 0; }

/* Section labels. Typed in sentence case in the editor and set in caps
   here, so the caps are a display choice rather than something baked
   into the content. */
.info-doc h2 {
  font-size: 14px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  line-height: 1.25;
  margin: 0 0 14px;
}

/* Bio column: larger, with open leading. */
.info-doc p {
  font-size: 16px;
  line-height: 1.625;
  margin: 0 0 16px;
}

/* Client and publication columns: a size down, with the leading pulled
   tight inside each entry and the air placed between entries instead.
   Long names like "The Elder Statesman" then wrap as one compact unit
   rather than opening a gap mid-name. */
.info-doc ul {
  list-style: none;
  margin: 0;
  padding: 0;
}
.info-doc li {
  font-size: 14px;
  line-height: 1.25;
  margin: 0 0 14px;
}

/* Lists sit under a label of the same size, so the label column reads
   a step smaller than the bio. */
.info-doc .wp-block-column:not(:first-child) h2 { font-size: 14px; }

.info-doc em,
.info-doc i { font-style: italic; }

.info-doc a { text-decoration: underline; text-underline-offset: 2px; }
.info-doc a:hover { opacity: 0.5; }

/* The Info page photo. Capped at --info-img-w rather than filling its
   column, so it stays modest on large screens. The !important beats any
   width or height WordPress writes onto a resized image block. */
.info-doc figure,
.info-doc .wp-block-image {
  margin: 0 0 28px;
  width: auto !important;
  max-width: var(--info-img-w);
}
.info-doc img {
  width: 100% !important;
  max-width: var(--info-img-w);
  height: auto !important;
}

/* Trailing credit line, set quiet. */
.info-doc .credit { color: var(--mute); }

/* ============================================================
   MOBILE
   ============================================================ */

@media (max-width: 800px) {
  :root {
    --slide-x: 12px;
    --slide-y: 12px;
    --cap-h: 18px;
    --bar-pad-b: 16px;
    --sheet-h: 175px;
    --pad: 14px;
  }

  .menu-btn { display: block; }

  .nav-right {
    display: none;
    position: absolute;
    top: var(--nav-h);
    left: 0; right: 0;
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
    padding: 14px var(--pad) 20px;
    background: var(--bg);
    color: var(--ink);
  }
  .nav.is-open .nav-right { display: flex; }
  .nav.is-open { mix-blend-mode: normal; background: var(--bg); color: var(--ink); }

  .work-list { position: static; display: flex; padding: 8px 0 0 12px; }

  .work-grid, .motion-grid { grid-template-columns: 1fr; gap: 20px; }

  /* Sidebar becomes a scrolling row of project names above the image. */
  .project-shell { display: block; }
  .project-main { grid-column: auto; }
  .sidebar {
    position: static;
    width: auto;
    margin-top: var(--nav-h);
    padding: 8px var(--pad);
    overflow-x: auto;
    white-space: nowrap;
    border-bottom: 1px solid var(--hair);
  }
  .sidebar ul { display: inline-flex; gap: 14px; }
  .sidebar .group { display: none; }
  .has-sidebar .bar { left: 0; }
  .has-sidebar .viewer { margin-top: 0; height: calc(100svh - var(--nav-h) - var(--bar-h) - 40px); }

  .bar-meta .bar-count { display: none; }

  /* Info columns stack in source order, and the type steps down a size
     the way the reference does below its desktop breakpoint. */
  .info-doc { padding-top: 24px; }
  .info-doc .wp-block-columns { gap: 0; flex-wrap: wrap; }
  .info-doc .wp-block-column { flex-basis: 100% !important; margin-bottom: 24px; }
  .info-doc p { font-size: 14px; }
  .info-doc li,
  .info-doc h2 { font-size: 12px; }
  .info-doc li { margin-bottom: 10px; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}
