/* ==========================================================================
   Shem Katz Photography — shared stylesheet
   Loaded by every page in the site. Edit tokens in :root to restyle
   everything at once (colors, fonts, spacing).
   ========================================================================== */

/* Bomstad Display — licensed display typeface, self-hosted from /fonts.
   Files live in the "Bomstad Display" folder at the repo root; these
   @font-face rules point at the WOFF2/WOFF copies in /fonts instead so
   the URLs don't have to deal with spaces in folder/file names. */
@font-face {
  font-family: "Bomstad Display";
  src: url("fonts/BomstadDisplay-Thin.woff2") format("woff2"),
       url("fonts/BomstadDisplay-Thin.woff") format("woff");
  font-weight: 100;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Bomstad Display";
  src: url("fonts/BomstadDisplay-ExtraLight.woff2") format("woff2"),
       url("fonts/BomstadDisplay-ExtraLight.woff") format("woff");
  font-weight: 200;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Bomstad Display";
  src: url("fonts/BomstadDisplay-Light.woff2") format("woff2"),
       url("fonts/BomstadDisplay-Light.woff") format("woff");
  font-weight: 300;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Bomstad Display";
  src: url("fonts/BomstadDisplay-Regular.woff2") format("woff2"),
       url("fonts/BomstadDisplay-Regular.woff") format("woff");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Bomstad Display";
  src: url("fonts/BomstadDisplay-Medium.woff2") format("woff2"),
       url("fonts/BomstadDisplay-Medium.woff") format("woff");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Bomstad Display";
  src: url("fonts/BomstadDisplay-SemiBold.woff2") format("woff2"),
       url("fonts/BomstadDisplay-SemiBold.woff") format("woff");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Bomstad Display";
  src: url("fonts/BomstadDisplay-Bold.woff2") format("woff2"),
       url("fonts/BomstadDisplay-Bold.woff") format("woff");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Bomstad Display";
  src: url("fonts/BomstadDisplay-ExtraBold.woff2") format("woff2"),
       url("fonts/BomstadDisplay-ExtraBold.woff") format("woff");
  font-weight: 800;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Bomstad Display";
  src: url("fonts/BomstadDisplay-Black.woff2") format("woff2"),
       url("fonts/BomstadDisplay-Black.woff") format("woff");
  font-weight: 900;
  font-style: normal;
  font-display: swap;
}

:root {
  --bg: #f7f6f3;
  --surface: #ffffff;
  --text: #1a1a18;
  --text-muted: #5c5a54;
  --accent: #3d5c46;
  --accent-soft: #e7ebe5;
  --error: #9a3b32;
  --error-soft: #f5e6e3;
  --border: #dedad2;
  --placeholder: #c9c4b8;
  --placeholder-alt: #b9c4b6;

  --font-display: "Bomstad Display", -apple-system, sans-serif;
  --font-body: "Inter", -apple-system, sans-serif;

  --max-width: 1150px;
  --gap: clamp(1.5rem, 4vw, 3rem);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #14140f;
    --surface: #1c1c16;
    --text: #f2f0e8;
    --text-muted: #a9a596;
    --accent: #7fa383;
    --accent-soft: #23281f;
    --error: #e08b7d;
    --error-soft: #2e1f1c;
    --border: #33322a;
    --placeholder: #2b2a23;
    --placeholder-alt: #262c22;
  }
}
:root[data-theme="dark"] {
  --bg: #14140f;
  --surface: #1c1c16;
  --text: #f2f0e8;
  --text-muted: #a9a596;
  --accent: #7fa383;
  --accent-soft: #23281f;
  --error: #e08b7d;
  --error-soft: #2e1f1c;
  --border: #33322a;
  --placeholder: #2b2a23;
  --placeholder-alt: #262c22;
}

* { box-sizing: border-box; }

html, body { margin: 0; }

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }

.container {
  max-width: var(--max-width);
  margin: 0 auto;
  padding: 0 1.5rem;
}

/* ==========================================================================
   HEADER / NAV
   Each menu item and dropdown entry is a real link to its own page —
   there is no in-page scrolling here. The desktop "Work" menu opens on
   hover/focus (":focus-within" keeps it usable with a keyboard). Below
   700px that hover menu is hidden and a native <details> menu takes
   over, so the same links stay reachable without any JavaScript.
   ========================================================================== */
header {
  position: sticky;
  top: 0;
  z-index: 20;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--border);
}

nav.container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-top: 1.1rem;
  padding-bottom: 1.1rem;
  gap: 1.5rem;
}

.wordmark {
  font-family: var(--font-display);
  font-size: 1.25rem;
  font-weight: 500;
}

.nav-right {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 1.5rem;
}

.nav-links {
  display: flex;
  gap: 2rem;
  font-size: 0.95rem;
  color: var(--text-muted);
}
.nav-links a:hover,
.nav-links a.current { color: var(--text); }
.nav-links a.current { text-decoration: underline; text-decoration-color: var(--accent); text-decoration-thickness: 2px; text-underline-offset: 6px; }

/* Language switch — small dropdown, always visible (desktop & mobile).
   It's the last item in nav-right, so it always sits at the far right
   of the header, after Work/About/Contact. The left border + padding
   give it a visual break from the main nav links. */
.lang-switch {
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  color: var(--text-muted);
  cursor: pointer;
  padding: 0.3rem 0.1rem 0.3rem 1.25rem;
  border-left: 1px solid var(--border);
}
.lang-switch:hover { color: var(--text); }
.lang-switch::after { content: " \25BE"; font-size: 0.7em; }
.lang-dropdown { min-width: 140px; }
/* Right-aligned to the EN/ES button so the menu never pokes past the
   screen edge (which caused a sideways scroll on mid-size windows). */
.lang-switch .lang-dropdown { left: auto; right: 0; transform: none; }
.lang-dropdown a.current { color: var(--accent); font-weight: 600; }

.has-dropdown { position: relative; }

.dropdown {
  position: absolute;
  /* top:0 + padding-top (instead of a margin-top gap) keeps the hover
     area continuous from trigger straight into the menu — a gap here
     is the classic bug where hover works only after a click/focus. */
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  margin-top: 0;
  padding-top: 0.6rem;
  background: transparent;
  min-width: 170px;
  display: flex;
  flex-direction: column;

  opacity: 0;
  visibility: hidden;
  transition: opacity 0.15s ease;
}
.dropdown-panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 0.5rem;
  display: flex;
  flex-direction: column;
  box-shadow: 0 8px 24px rgba(0,0,0,0.12);
  transform: translateY(-4px);
  transition: transform 0.15s ease;
}

.has-dropdown:hover .dropdown,
.has-dropdown:focus-within .dropdown {
  opacity: 1;
  visibility: visible;
}
.has-dropdown:hover .dropdown-panel,
.has-dropdown:focus-within .dropdown-panel {
  transform: translateY(0);
}

.dropdown a {
  padding: 0.5rem 0.75rem;
  font-size: 0.9rem;
  border-radius: 3px;
  white-space: nowrap;
  color: var(--text-muted);
}
.dropdown a:hover { background: var(--bg); color: var(--text); }
.dropdown a.current { color: var(--accent); font-weight: 600; }

@media (prefers-reduced-motion: reduce) {
  .dropdown { transition: none; }
}

@media (max-width: 700px) {
  .nav-links { display: none; }
}

/* Mobile menu (native <details>, no JS) */
.mobile-menu { display: none; }
@media (max-width: 700px) {
  .mobile-menu { display: block; position: relative; }
}
.mobile-menu summary {
  cursor: pointer;
  list-style: none;
  font-size: 0.95rem;
  color: var(--text);
  padding: 0.4rem 0.1rem;
}
.mobile-menu summary::-webkit-details-marker { display: none; }
.mobile-menu summary::after { content: "Menu ▾"; }
.mobile-menu[open] summary::after { content: "Menu ▴"; }
.mobile-menu[open] summary { content: ""; }
.mobile-panel {
  position: absolute;
  right: 0;
  top: calc(100% + 0.25rem);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.75rem 1rem;
  min-width: 190px;
  box-shadow: 0 12px 28px rgba(0,0,0,0.14);
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.mobile-panel a { font-size: 0.95rem; color: var(--text-muted); padding: 0.15rem 0; }
.mobile-panel a.current { color: var(--accent); font-weight: 600; }
.mobile-panel .sub-label { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-muted); margin-top: 0.4rem; }
.mobile-panel hr { border: none; border-top: 1px solid var(--border); margin: 0.3rem 0; width: 100%; }

/* ==========================================================================
   HERO — full-bleed, rotating photos
   Each photo lives once, in its gallery folder (images/land/, images/couples/
   and so on); the home page points at those same files rather than copies.
   One .hero-slide per photo, set below with
     background-image: url('images/underwater/PB300088-web.jpg');
   Slides fade in sequence, 6s each. Adding or removing one means three
   edits: a .hero-slide in the HTML, an :nth-child rule below with its own
   delay 6s after the last, and the heroFade cycle length (slides x 6s)
   plus its hold keyframe (100 / number of slides) and the fade-out 8 points
   after that.
   The crossfade is pure CSS (see @keyframes heroFade below) so it needs
   no JavaScript — it keeps rotating even if scripts are blocked.
   ========================================================================== */
.hero {
  position: relative;
  /* The photos are 4:3, so a short hero on a wide window crops away most of
     the frame — `cover` can only show a band as tall as the hero itself.
     Growing the height with the window (52vw) keeps far more of each photo
     in view; the 82vh and 820px caps stop it swallowing the screen, and the
     440px floor keeps it a hero rather than a strip on narrow windows. */
  height: clamp(440px, min(52vw, 82vh), 820px);
  overflow: hidden;
  display: flex;
  align-items: flex-end;
}

.hero-slide {
  position: absolute;
  inset: 0;
  background: var(--placeholder) center/cover;
  opacity: 0;
  animation: heroFade 36s infinite;
  /* Linear, not the default ease: the outgoing and incoming opacities then
     add up to 1 all the way through the crossfade, so the hero never dips
     dark between photos. */
  animation-timing-function: linear;
}
/* Only the first photo downloads with the page. With JavaScript on (the
   "js" class is set by a one-line script in the <head>), the other slides'
   backgrounds are held back until hero-slides.js adds .bg-ready once the
   page has loaded, so they no longer compete with the first photo and the
   rest of the page. With JavaScript off they all load as normal. */
.js .hero:not(.bg-ready) .hero-slide:not(:first-child) { background-image: none; }
.hero-slide:nth-child(1) {
  animation-delay: 0s;
  background-image: url('images/land/DSC01937-web.jpg');
  /* The couple stand left of centre: keep them in frame on narrow screens. */
  background-position: 25% center;
}
.hero-slide:nth-child(2) {
  animation-delay: 6s;
  background-image: url('images/editorial/DSC01556-web.jpg');
  /* Lower than centre so the heads sit closer to the top of the hero. */
  background-position: center 70%;
}
.hero-slide:nth-child(3) {
  animation-delay: 12s;
  background-image: url('images/underwater/PB090028-web.jpg');
}
.hero-slide:nth-child(4) {
  animation-delay: 18s;
  background-image: url('images/underwater/PB300088-web.jpg');
}
.hero-slide:nth-child(5) {
  animation-delay: 24s;
  background-image: url('images/underwater/PC050119-web.jpg');
  /* The turtle sits high in the frame. 18% down the overflow puts its head
     and fins near the top of the hero while leaving the reef below it in
     shot — closer to the top than centre, without pinning it to the edge.
     Adjust this one number per photo. */
  background-position: center 18%;
}
.hero-slide:nth-child(6) {
  animation-delay: 30s;
  background-image: url('images/land/DSC02262-web.jpg');
}

/* Phones/tablets (up to ~900px wide) and ordinary-density screens up to
   1600px wide: a 1600px copy of each photo is still pin-sharp there and
   about a third lighter than the full 2000px file. The lazy-loading rule above still wins
   for slides 2-6 until the page has loaded. */
@media (max-width: 900px), (max-width: 1600px) and (max-resolution: 1.5dppx) {
  .hero-slide:nth-child(1) { background-image: url('images/land/DSC01937-web-1600.jpg'); }
  .hero-slide:nth-child(2) { background-image: url('images/editorial/DSC01556-web-1600.jpg'); }
  .hero-slide:nth-child(3) { background-image: url('images/underwater/PB090028-web-1600.jpg'); }
  .hero-slide:nth-child(4) { background-image: url('images/underwater/PB300088-web-1600.jpg'); }
  .hero-slide:nth-child(5) { background-image: url('images/underwater/PC050119-web-1600.jpg'); }
  .hero-slide:nth-child(6) { background-image: url('images/land/DSC02262-web-1600.jpg'); }
}

/* Manual control — hero-slides.js adds the arrows and, once one is used,
   puts .is-manual on the hero: the CSS rotation stops and the script
   crossfades between slides instead. Without JavaScript none of this
   exists and the animation below just keeps running. */
.slide-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 3;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 1px solid rgba(255,255,255,0.35);
  border-radius: 999px;
  background: rgba(20,20,15,0.28);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  color: #fdfcf9;
  cursor: pointer;
  /* Visible at rest so they are discoverable, brighter on hover/focus. */
  opacity: 0.55;
  transition: opacity 0.3s ease, background-color 0.3s ease, border-color 0.3s ease;
}
.slide-arrow--prev { left: clamp(0.75rem, 2vw, 1.75rem); }
.slide-arrow--next { right: clamp(0.75rem, 2vw, 1.75rem); }
[data-slideshow]:hover .slide-arrow,
[data-slideshow]:focus-within .slide-arrow,
.slide-arrow:focus-visible { opacity: 1; }
.slide-arrow:hover {
  background: rgba(20,20,15,0.5);
  border-color: rgba(255,255,255,0.6);
}
/* No hover on touch screens, so leave them showing there. */
@media (hover: none) {
  .slide-arrow { opacity: 1; }
}

.hero.is-manual .hero-slide {
  animation: none;
  opacity: 0;
  transition: opacity 0.7s linear;   /* same reason as above */
}
.hero.is-manual .hero-slide.is-active { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .hero.is-manual .hero-slide { transition: none; }
}

@keyframes heroFade {
  0%    { opacity: 0; }
  6.67% { opacity: 1; }
  16.67% { opacity: 1; }  /* hold until the next slide is due (100 / 6) */
  23.33% { opacity: 0; }   /* falls exactly as the next one rises: no dip */
  100%  { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .hero-slide { animation: none; opacity: 0; }
  .hero-slide:nth-child(1) { opacity: 1; }
}

.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  /* Deep enough to keep the headline legible over the bright over-under
     frame, where the text falls on sunlit coral rather than dark water. */
  background: linear-gradient(to top, rgba(0,0,0,0.68), rgba(0,0,0,0) 62%);
}

.hero-content {
  position: relative;
  z-index: 2;
  padding: 2.5rem 1.5rem;
  max-width: var(--max-width);
  margin: 0 auto;
  width: 100%;
  color: #fdfcf9;
}

.hero-content h1 {
  font-family: var(--font-display);
  font-style: normal;
  font-weight: 600;
  font-size: clamp(2rem, 5vw, 3.2rem);
  margin: 0 0 0.5rem;
  text-wrap: balance;
}

.hero-content p {
  max-width: 42ch;
  opacity: 0.9;
  margin: 0;
}
/* Location line under the headline: same display face, lighter and
   letter-spaced so it reads as a quiet caption rather than a second title. */
.hero-content .hero-place {
  font-family: var(--font-display);
  font-weight: 300;
  font-size: clamp(0.8rem, 1.4vw, 0.95rem);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  opacity: 0.85;
  max-width: none;
}

/* ==========================================================================
   PAGE HEADER — the quieter opener used on every page besides Home
   ========================================================================== */
.page-header {
  padding: clamp(2.5rem, 6vw, 4rem) 0 clamp(1.5rem, 4vw, 2rem);
  border-bottom: 1px solid var(--border);
}
.page-header .eyebrow {
  font-size: 0.8rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin: 0 0 0.75rem;
}
.page-header h1 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.8rem, 4vw, 2.6rem);
  margin: 0 0 0.6rem;
  text-wrap: balance;
}
.page-header p {
  color: var(--text-muted);
  max-width: 56ch;
  margin: 0;
}

/* ==========================================================================
   ABOUT TEASER (home page)
   ========================================================================== */
.about-teaser {
  padding: clamp(2.5rem, 6vw, 4rem) 0;
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: var(--gap);
  align-items: center;
}
@media (max-width: 700px) {
  .about-teaser { grid-template-columns: 1fr; }
}
.about-teaser .about-photo {
  aspect-ratio: 1;
  background: var(--placeholder);
  border-radius: 3px;
  width: 100%;
}
.about-teaser h2 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.6rem;
  margin: 0 0 0.6rem;
}
.about-teaser p {
  color: var(--text-muted);
  max-width: 58ch;
  margin: 0 0 0.9rem;
}
.about-teaser a.cta {
  font-size: 0.85rem;
  color: var(--accent);
  font-weight: 600;
}
.about-teaser a.cta:hover { text-decoration: underline; }

/* ==========================================================================
   FULL ABOUT (about.html)
   ========================================================================== */
.about-full {
  padding: 1rem 0 5rem;
  display: grid;
  grid-template-columns: 1fr 1.3fr;
  gap: var(--gap);
}
@media (max-width: 800px) {
  .about-full { grid-template-columns: 1fr; }
}
.about-full h2 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.8rem;
  margin-top: 0;
}
.about-full .about-photo {
  aspect-ratio: 1;
  background: var(--placeholder);
  border-radius: 3px;
  max-width: 320px;
}

/* A real photo dropped inside .about-photo fills the square crop; without
   one the block stays a flat placeholder. */
.about-photo:has(img) { background: none; }
.about-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 3px;
  display: block;
}
.about-full p { color: var(--text-muted); }

/* ==========================================================================
   COMPARE — before/after slider (editing.html)
   Two stacked "photos" (.compare-before behind, .compare-after clipped on
   top) plus an invisible native <input type="range"> layered over the
   whole thing. compare-slider.js listens for that range's input event and
   writes the --pos custom property, which both the clip-path and the
   divider's position read from. Using a real range input (rather than
   custom pointer-tracking) means dragging, clicking, and arrow-key
   keyboard control all work for free, and it stays usable with no JS if
   scripts are ever blocked (the divider just sits at 50%).
   ========================================================================== */
.compare-section {
  padding: clamp(1.5rem, 4vw, 2.5rem) 0 5rem;
  display: flex;
  flex-direction: column;
  gap: clamp(2rem, 5vw, 3rem);
}
.compare-wrap { max-width: 640px; margin: 0 auto; width: 100%; }
.compare {
  position: relative;
  /* Horizontal drags move the slider (compare-slider.js); vertical swipes
     still scroll the page on phones. */
  touch-action: pan-y;
  cursor: ew-resize;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  /* --ratio lets each pair match its own frame, so nothing is cropped;
     3/2 stays the default for pairs that don't set one. */
  aspect-ratio: var(--ratio, 3 / 2);
  border-radius: 4px;
  overflow: hidden;
  background: var(--placeholder);
}
.compare-media { position: absolute; inset: 0; }
.compare-img {
  position: absolute;
  inset: 0;
  background: var(--placeholder) center/cover;
}
/* Swap these two backgrounds for real photos — see the HTML comment
   above each .compare-wrap in editing.html. */
.compare-before { background-color: var(--placeholder); }
.compare-after {
  background-color: var(--placeholder-alt);
  /* The edited frame shows from the left edge up to the handle, the
     unedited one beyond it. So dragging toward the Before label (left)
     uncovers the unedited photo, and toward After (right) the edited one —
     each end of the slider shows exactly the label beneath it. */
  clip-path: inset(0 calc(100% - var(--pos, 50%)) 0 0);
}

/* Each before/after pair names its two frames here. The paths resolve from
   this stylesheet, so the same rule serves the English and Spanish pages. */
.edit-01 .compare-before { background-image: url('images/edits/unedited-2020077-web.jpg'); }
.edit-01 .compare-after  { background-image: url('images/underwater/P2020077-web.jpg'); }
.compare-divider {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--pos, 50%);
  width: 2px;
  transform: translateX(-1px);
  background: #fff;
  box-shadow: 0 0 0 1px rgba(0,0,0,0.15);
  pointer-events: none;
}
.compare-divider::after {
  content: "\21d4";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: #fff;
  color: #1a1a18;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1rem;
  box-shadow: 0 2px 10px rgba(0,0,0,0.25);
}
.compare-range {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  /* Pointer and touch input is handled on .compare by the script; the
     range only serves keyboard and screen-reader users. */
  pointer-events: none;
  -webkit-appearance: none;
  appearance: none;
}
.compare-range::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 44px;
  height: 100%;
}
.compare-range::-moz-range-thumb {
  width: 44px;
  height: 100%;
  border: none;
  background: transparent;
}
.compare-range:focus-visible ~ .compare-divider {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.compare-labels {
  display: flex;
  justify-content: space-between;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
  margin-top: 0.6rem;
}

@media (prefers-reduced-motion: reduce) {
  .compare-after { transition: none; }
}

/* ==========================================================================
   FEATURED FRAME (index.html) — a single photo shown whole rather than
   cropped into a band, so a portrait frame keeps its shape. Swap the
   <img> in the markup; the column adapts to whatever aspect ratio it has.
   ========================================================================== */
.featured {
  padding: clamp(2.5rem, 6vw, 4rem) 0;
  border-top: 1px solid var(--border);
  display: grid;
  grid-template-columns: 1fr minmax(0, 380px);
  gap: var(--gap);
  align-items: center;
}
.featured-text { grid-column: 1; grid-row: 1; max-width: 44ch; }
.featured-photo {
  grid-column: 2;
  grid-row: 1;
  margin: 0;
  /* The two frames are 2:3 and 3:4. Stacking them for a crossfade needs one
     fixed shape, and 2:3 is the safer choice: it trims a little from the
     sides of the wider frame rather than cropping the taller one's top and
     bottom, where the subjects sit closer to the edge. */
  position: relative;
  aspect-ratio: 2 / 3;
  overflow: hidden;
  border-radius: 3px;
}
@media (max-width: 760px) {
  .featured { grid-template-columns: 1fr; }
  .featured-text, .featured-photo { grid-column: 1; grid-row: auto; }
  .featured-photo { max-width: 380px; }
}
.featured-slide {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  opacity: 0;
  animation: featuredFade 24s infinite;
  animation-timing-function: linear;   /* so the crossfade never dips */
}
.featured-slide:nth-child(1) { animation-delay: 0s; }
.featured-slide:nth-child(2) { animation-delay: 6s; }
.featured-slide:nth-child(3) { animation-delay: 12s; }
.featured-slide:nth-child(4) { animation-delay: 18s; }
.featured-slide:nth-child(5) { animation-delay: 24s; }

/* Four slides, 6s each: each fade-out lines up exactly with the next fade-in. */
@keyframes featuredFade {
  0%    { opacity: 0; }
  4.17% { opacity: 1; }
  25%   { opacity: 1; }
  29.17% { opacity: 0; }
  100%  { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .featured-slide { animation: none; opacity: 0; }
  .featured-slide:nth-child(1) { opacity: 1; }
}

.featured-photo.is-manual .featured-slide {
  animation: none;
  opacity: 0;
  transition: opacity 0.7s linear;
}
.featured-photo.is-manual .featured-slide.is-active { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .featured-photo.is-manual .featured-slide { transition: none; }
}

/* Smaller arrows here than on the full-bleed hero. */
.featured-photo .slide-arrow { width: 34px; height: 34px; }
.featured-photo .slide-arrow svg { width: 15px; height: 15px; }
.featured-photo .slide-arrow--prev { left: 0.6rem; }
.featured-photo .slide-arrow--next { right: 0.6rem; }
.featured .eyebrow {
  font-size: 0.8rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin: 0 0 0.75rem;
}
.featured h2 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.5rem, 3vw, 2rem);
  margin: 0 0 0.6rem;
}
.featured p { color: var(--text-muted); margin: 0 0 0.9rem; }
.featured a.cta { font-size: 0.85rem; color: var(--accent); font-weight: 600; }
.featured a.cta:hover { text-decoration: underline; }
/* "See more of my work" — same dropdown as Work in the nav, opened by hover
   or focus (a tap on touch screens), but left-aligned under the link. */
.cta-dropdown { display: inline-block; cursor: pointer; }
.cta-dropdown .cta { font-size: 0.85rem; color: var(--accent); font-weight: 600; }
.cta-dropdown:hover .cta,
.cta-dropdown:focus-within .cta { text-decoration: underline; }
.cta-dropdown .dropdown { left: 0; transform: none; z-index: 5; }
.cta-dropdown:focus { outline: none; }
.cta-dropdown:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* ==========================================================================
   TILES — Shop / Journal / Book a session (home page)
   ========================================================================== */
.tiles-section { padding: 0 0 clamp(2.5rem, 6vw, 4rem); }
.tiles {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.25rem;
}
@media (max-width: 800px) {
  .tiles { grid-template-columns: 1fr; }
}
.tile {
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 1.5rem;
  background: var(--surface);
  display: block;
}
.tile:hover { border-color: var(--accent); }
.tile h3 {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 1.1rem;
  margin: 0 0 0.5rem;
}
.tile p {
  color: var(--text-muted);
  font-size: 0.92rem;
  margin: 0 0 0.9rem;
}
.tile .status {
  display: inline-block;
  font-size: 0.72rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--accent);
  background: var(--accent-soft);
  padding: 0.25rem 0.6rem;
  border-radius: 999px;
}

/* ==========================================================================
   SERVICES — the three-up on work-commercial.html reuses the home page
   .tiles grid; this only restores the top padding .tiles-section drops,
   and styles the line that follows the tiles.
   ========================================================================== */
.services-section { padding: clamp(1.5rem, 4vw, 2.5rem) 0 0; }
.services-note {
  color: var(--text-muted);
  font-size: 0.92rem;
  margin: 1.25rem 0 0;
  max-width: 60ch;
}
.services-note a { color: var(--accent); font-weight: 600; }
.services-note a:hover { text-decoration: underline; }

/* ==========================================================================
   GALLERY — used on Work category pages
   ========================================================================== */
.gallery-section { padding: clamp(1.5rem, 4vw, 2.5rem) 0 5rem; }
.section-label {
  font-size: 0.85rem;
  color: var(--text-muted);
  margin-bottom: 1.5rem;
}
.gallery {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: 180px;
  grid-auto-flow: dense;
  gap: 0.6rem;
}
@media (max-width: 700px) {
  .gallery { grid-template-columns: repeat(2, 1fr); grid-auto-rows: 140px; }
}
.photo {
  background: var(--placeholder);
  border-radius: 2px;
  display: flex;
  align-items: flex-end;
  padding: 0.6rem;
  color: var(--text-muted);
  font-size: 0.75rem;
}
.photo.wide { grid-column: span 2; }
.photo.tall { grid-row: span 2; }
/* A lone wide tile closing out a gallery: centre it instead of leaving a
   hole on the right. Only on the 4-column grid; on phones it is full width
   anyway. */
@media (min-width: 701px) {
  .photo.wide.center { grid-column: 2 / span 2; }
}
.photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.photo:has(img) { padding: 0; }

/* ==========================================================================
   COMING SOON — Shop / Journal / Book a session pages
   ========================================================================== */
.coming-soon {
  padding: clamp(3rem, 10vw, 6rem) 0;
  text-align: center;
  max-width: 46ch;
  margin: 0 auto;
}
.coming-soon .status {
  display: inline-block;
  font-size: 0.72rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--accent);
  background: var(--accent-soft);
  padding: 0.3rem 0.7rem;
  border-radius: 999px;
  margin-bottom: 1rem;
}
.coming-soon h1 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.8rem, 5vw, 2.4rem);
  margin: 0 0 0.75rem;
}
.coming-soon p { color: var(--text-muted); margin: 0 0 1.5rem; }
.coming-soon a.back {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--accent);
}
.coming-soon a.back:hover { text-decoration: underline; }

/* ==========================================================================
   CONTACT
   ========================================================================== */
.contact-section {
  padding: 1rem 0 clamp(3rem, 6vw, 5rem);
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--gap);
}
@media (max-width: 800px) {
  .contact-section { grid-template-columns: 1fr; }
}
.contact-section h2 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.6rem;
  margin-top: 0;
}
.contact-section > div:first-child p { color: var(--text-muted); }

.contact-narrow { max-width: 560px; margin: 0 auto; padding: 1rem 0 4rem; }

/* ".page-header p" (used for the intro paragraph above this) sets
   margin:0 and, being more specific than ".direct-label" alone, was
   winning and cancelling this spacing — "p.direct-label" beats it. */
p.direct-label {
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
  margin: 1.75rem 0 0.6rem;
}
.contact-direct {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem;
}
.contact-direct a {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.9rem;
  color: var(--text-muted);
}
.contact-direct a:hover { color: var(--accent); }
.contact-direct svg { flex-shrink: 0; }

form.contact-form {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
}
.contact-form label {
  font-size: 0.85rem;
  color: var(--text-muted);
  margin-bottom: 0.3rem;
  display: block;
}
.contact-form input,
.contact-form textarea {
  width: 100%;
  padding: 0.65rem 0.8rem;
  border: 1px solid var(--border);
  border-radius: 3px;
  background: var(--surface);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 0.95rem;
}
.contact-form textarea { resize: vertical; min-height: 100px; }
.contact-form button {
  align-self: flex-start;
  padding: 0.7rem 1.6rem;
  background: var(--accent);
  color: #fff;
  border: none;
  border-radius: 3px;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.9rem;
  cursor: pointer;
}
.contact-form button:hover { opacity: 0.9; }

.contact-form input:focus-visible,
.contact-form textarea:focus-visible,
.contact-form button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.contact-form button:disabled { opacity: 0.7; cursor: default; }

.form-status {
  margin-top: 1rem;
  padding: 0.65rem 0.9rem;
  border-radius: 3px;
  font-size: 0.9rem;
}
.form-status.success { color: var(--accent); background: var(--accent-soft); }
.form-status.error { color: var(--error); background: var(--error-soft); }

/* ==========================================================================
   FOOTER — identical on every page
   ========================================================================== */
footer {
  border-top: 1px solid var(--border);
  padding: 2rem 0;
}
footer .container {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 1rem;
  align-items: center;
}
.social-links { display: flex; gap: 1rem; }
.social-links a {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.75rem;
  color: var(--text-muted);
}
.social-links a:hover { border-color: var(--accent); color: var(--accent); }
.footer-meta { color: var(--text-muted); font-size: 0.85rem; }

a:focus-visible, button:focus-visible, summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
  *:not(.hero-slide) { transition: none !important; }
}

/* ==========================================================================
   SMALL SCREENS
   Sections such as .about-teaser or .featured set `padding: X 0`, which
   also wiped out the container's side padding, so on phones their text and
   photos ran into the screen edges. Re-applied here, last in the file, so
   every section keeps the same side margin as the header and footer.
   ========================================================================== */
.container {
  padding-left: 1.5rem;
  padding-right: 1.5rem;
}
@media (max-width: 480px) {
  .container { padding-left: 1.25rem; padding-right: 1.25rem; }
}

@media (max-width: 700px) {
  /* Home — About teaser: a modest portrait beside the heading rather than a
     full-width square that fills the whole screen. */
  .about-teaser {
    grid-template-columns: 104px 1fr;
    column-gap: 1.25rem;
    row-gap: 1rem;
    align-items: start;
  }
  .about-teaser .about-photo { grid-row: 1; align-self: start; }
  .about-teaser .about-photo img { aspect-ratio: 4 / 5; height: auto; }
  .about-teaser .about-photo { aspect-ratio: auto; }
  .about-teaser h2 { margin-top: 0.2rem; }

  /* Home — Portraits: text first, then the photo at a comfortable size,
     centred instead of stretched edge to edge. */
  .featured { gap: 1.75rem; }
  .featured-photo { width: 100%; max-width: 320px; justify-self: center; }

  /* About page — portrait at a sensible size on phones. */
  .about-full .about-photo { max-width: 240px; }

  /* Galleries — rows sized from the screen width so every tile keeps the
     same proportions as on a computer: small tiles 3:2, tall tiles about
     3:4, big tiles 3:2. Fixed 140px rows were cropping the photos hard. */
  .gallery { grid-auto-rows: calc((100vw - 2.5rem - 0.6rem) / 3); }
}

/* ==========================================================================
   PACKAGES + BOOKING — Couples & Proposals page and Book a Session page
   ========================================================================== */
.btn {
  display: inline-block;
  background: var(--accent);
  color: #fdfcf9;
  font-weight: 600;
  font-size: 0.9rem;
  padding: 0.7rem 1.2rem;
  border-radius: 999px;
  transition: opacity 0.2s ease;
}
.btn:hover { opacity: 0.88; }
.tile.package { display: flex; flex-direction: column; }
.tile.package .package-price {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 1.5rem;
  color: var(--accent);
  margin: 0.1rem 0 0.9rem;
}
.package-price .package-from {
  font-family: var(--font-body);
  font-size: 0.8rem;
  font-weight: 400;
  color: var(--text-muted);
}
.tile.package ul {
  margin: 0 0 1.25rem;
  padding-left: 1.1rem;
  color: var(--text-muted);
  font-size: 0.92rem;
}
.tile.package li { margin-bottom: 0.3rem; }
.tile.package .btn { margin-top: auto; align-self: flex-start; }
.package-extras { color: var(--text-muted); font-size: 0.9rem; margin: 1.1rem 0 0; }
#packages .section-label, .steps-section .section-label { margin-bottom: 1rem; }

.steps-section { padding-top: clamp(2rem, 5vw, 3rem); }
.steps {
  list-style: none;
  counter-reset: step;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.25rem;
}
@media (max-width: 800px) {
  .steps { grid-template-columns: 1fr; }
}
.steps li { counter-increment: step; border-top: 1px solid var(--border); padding-top: 1rem; }
.steps h3 {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 1.05rem;
  margin: 0 0 0.4rem;
}
.steps h3::before {
  content: counter(step) ".";
  color: var(--accent);
  margin-right: 0.4rem;
}
.steps p { color: var(--text-muted); font-size: 0.92rem; margin: 0; }
.booking .btn { margin: 0.5rem 0 0.5rem; }

/* Home — Couples frame: seven photos, 6s each (the Portraits frame below
   has five, so it keeps the 30s featuredFade cycle). */
.featured--couples .featured-slide { animation-name: featuredFade7; animation-duration: 42s; }
.featured-slide:nth-child(6) { animation-delay: 30s; }
.featured-slide:nth-child(7) { animation-delay: 36s; }
@keyframes featuredFade7 {
  0%     { opacity: 0; }
  2.38%  { opacity: 1; }
  14.29% { opacity: 1; }
  16.67% { opacity: 0; }
  100%   { opacity: 0; }
}
/* Portraits follows directly after Couples: no second divider line. */
.featured--couples + .featured { border-top: none; padding-top: 0; }
.services-intro { color: var(--text-muted); max-width: 62ch; margin: 0 0 1.25rem; }
#dive-trips .section-label { margin-bottom: 0.75rem; }
#dive-trips .package-extras { margin-bottom: 0.9rem; }
.prints-cta { margin: 1.75rem 0 0.25rem; }
.prints-section { padding-bottom: 4rem; }

/* Narrow laptops/tablets (just above the phone menu): tighten the menu so
   Work, Prints, About, Editing and Contact still fit on one line. */
@media (min-width: 701px) and (max-width: 900px) {
  .nav-links { gap: 1.1rem; font-size: 0.9rem; }
  .nav-right { gap: 1rem; }
}
