
  :root{
    --blue:#4c82be;
    --blue-deep:#3a668f;
    --blue-tint:rgba(76,130,190,.1);
    --greyblue:#939fbf;      /* decorative + small text on DARK surfaces only */
    --muted:#5a6175;         /* small text on light surfaces (AA: 4.6:1 on --wall) */
    --slate:#2b3242;
    --wall:#dbdfdf;
    --mat:#fcfdfc;
    --olive:#5b5c10;
    --ink:#252a35;
    --display:"Prata",Georgia,serif;
    --body:"Jost","Helvetica Neue",Arial,sans-serif;
    --maxw:1200px;
    --r-card:16px;
    --shadow:0 14px 34px -20px rgba(43,50,66,.35);
  }
  *{margin:0;padding:0;box-sizing:border-box}
  html{scroll-behavior:smooth}
  @media (prefers-reduced-motion:reduce){
    html{scroll-behavior:auto}
    *,*::before,*::after{animation:none!important;transition:none!important}
  }
  body{font-family:var(--body);font-weight:300;color:var(--ink);background:var(--wall);line-height:1.7;font-size:17px}
  img{display:block;max-width:100%}
  a{color:inherit}
  a:focus-visible,button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible{outline:3px solid var(--blue);outline-offset:3px;border-radius:6px}

  .wrap{max-width:var(--maxw);margin:0 auto;padding:0 var(--gutter,28px)}
  section{padding:100px 0}
  h1,h2,h3{font-family:var(--display);font-weight:400;line-height:1.18}
  h2{font-size:clamp(1.9rem,3.6vw,2.7rem);margin:.7rem 0 1.2rem}
  .lede{max-width:58ch;font-size:1.05rem;color:#3d4352}

  /* eyebrow → soft badge, mixed case (was uppercase+rule) */
  .badge{display:inline-flex;align-items:center;gap:8px;font-size:.85rem;font-weight:500;color:var(--blue-deep);background:var(--blue-tint);border-radius:999px;padding:7px 18px}
  .badge::before{content:"✦";font-size:.7em;color:var(--blue)}
  .dark .badge{background:rgba(147,159,191,.16);color:#c3cde2}

  /* buttons → pills, mixed case, sliding arrow */
  .btn{display:inline-flex;align-items:center;gap:10px;font-weight:500;font-size:.95rem;text-decoration:none;padding:14px 30px;border-radius:999px;border:1.5px solid transparent;transition:all .25s;cursor:pointer;font-family:var(--body)}
  .btn .arr{transition:transform .25s;font-weight:400}
  .btn:hover .arr{transform:translateX(5px)}
  .btn-solid{background:var(--blue);color:#fff}
  .btn-solid:hover{background:var(--blue-deep)}
  .btn-ring{border-color:var(--blue);color:var(--blue-deep);background:transparent}
  .btn-ring:hover{background:var(--blue-tint)}
  .btn-ring-light{border-color:rgba(255,255,255,.75);color:#fff}
  .btn-ring-light:hover{background:rgba(255,255,255,.14)}

  /* matted frame — square on purpose: artwork is square, interface is round */
  .matted{background:var(--mat);padding:14px;border:1px solid rgba(147,159,191,.4);box-shadow:var(--shadow)}
  .matted .ph{overflow:hidden;position:relative}
  .matted img{width:100%;height:100%;object-fit:cover;transition:transform .6s ease}
  .matted:hover img{transform:scale(1.04)}
  .plate{display:flex;justify-content:space-between;align-items:baseline;gap:12px;padding:12px 4px 2px}
  .plate h3{font-size:1.02rem;transition:color .25s}
  .matted:hover .plate h3{color:var(--blue-deep)}
  .plate .fn{font-size:.78rem;font-weight:400;color:var(--muted);white-space:nowrap;font-style:italic}

  /* wordmark */
  .mark{font-family:var(--display);font-size:1.15rem;letter-spacing:.04em;text-decoration:none;white-space:nowrap}
  .mark .o{position:relative;display:inline-block}
  .mark .o::after{content:"✦";position:absolute;top:50%;left:50%;transform:translate(-50%,-54%);font-size:.36em;color:var(--blue)}
  .mark small{display:block;font-family:var(--body);font-weight:400;font-size:.62rem;letter-spacing:.34em;text-transform:uppercase;color:var(--blue);margin-top:1px}

  /* header — mixed-case nav, dot hover (was uppercase + border-bottom) */
  header{position:sticky;top:0;z-index:50;background:rgba(252,253,252,.94);backdrop-filter:blur(10px);border-bottom:1px solid rgba(147,159,191,.3)}
  .nav{display:flex;align-items:center;justify-content:space-between;padding:13px 28px;max-width:var(--maxw);margin:0 auto}
  nav ul{display:flex;gap:34px;list-style:none;align-items:center}
  nav a{font-size:.97rem;font-weight:400;text-decoration:none;position:relative;padding:6px 2px;transition:color .2s}
  nav a::after{content:"";position:absolute;left:50%;bottom:-3px;width:5px;height:5px;border-radius:50%;background:var(--blue);transform:translateX(-50%) scale(0);transition:transform .22s}
  nav a:hover{color:var(--blue-deep)}
  nav a:hover::after{transform:translateX(-50%) scale(1)}
  nav a[aria-current="page"],
  .current-menu-item>a{color:var(--blue-deep)}
  .current-menu-item>a::after{transform:translateX(-50%) scale(1)}
  .nav-cta{border:1.5px solid var(--blue);border-radius:999px;padding:8px 22px!important;color:var(--blue-deep)}
  .nav-cta::after{display:none}
  .nav-cta:hover{background:var(--blue);color:#fff}
  .menu-toggle{display:none;background:none;border:1.5px solid var(--blue);border-radius:999px;color:var(--blue-deep);font-family:var(--body);font-size:.85rem;padding:8px 18px;cursor:pointer}

  /* hero */
  .hero{position:relative;min-height:94vh;display:flex;align-items:center;justify-content:center;text-align:center;color:#eef1f4;padding:0}
  .hero::before{content:"";position:absolute;inset:0;background:var(--hero-img,var(--slate)) center/cover no-repeat}
  .hero::after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,rgba(43,50,66,.38),rgba(43,50,66,.12) 45%,rgba(43,50,66,.55))}
  .hero-inner{position:relative;z-index:2;padding:0 28px;max-width:900px}
  .hero h1{font-size:clamp(2.4rem,7vw,4.6rem);letter-spacing:.12em;text-transform:uppercase;text-shadow:0 2px 24px rgba(43,50,66,.5)}
  .hero .sub{font-weight:300;font-size:clamp(1rem,2.2vw,1.5rem);letter-spacing:.5em;text-transform:uppercase;color:#dbdfdf;margin-top:10px}
  .hero .tag{margin:30px auto 40px;max-width:52ch;font-size:1.05rem;color:#e4e8ec}
  .hero-cta{display:flex;gap:16px;justify-content:center;flex-wrap:wrap}
  .hero .fn-strip{position:absolute;bottom:26px;left:0;right:0;text-align:center;font-size:.85rem;font-style:italic;color:#c6ccd6;z-index:2}
  .hero .fn-strip span+span::before{content:"·";margin:0 12px;font-style:normal}

  /* meet */
  .meet{background:var(--mat)}
  .meet .wrap{display:grid;grid-template-columns:.9fr 1.1fr;gap:76px;align-items:center}
  .meet .matted{transform:rotate(-1.2deg)}
  .meet .matted .ph{aspect-ratio:4/5}
  .meet p+p{margin-top:1em}
  .sig{font-family:var(--display);font-style:italic;font-size:1.3rem;color:var(--blue);margin-top:1.5em}

  /* collections */
  .collections{background:var(--wall)}
  .wall-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:34px;margin-top:56px}
  .wall-grid .matted{text-decoration:none}
  .wall-grid .ph{aspect-ratio:4/3}
  .wall-grid .c-tall .ph{aspect-ratio:3/4}
  /* Three equal columns, matching the row above.
     
     This was 1.4fr + 1fr + 1fr — the prototype's editorial accent, one wide tile
     beside two narrow. With six collections of equal standing it stopped reading
     as composition and started reading as a mistake: widths 443/316/316, frame
     heights 258/179/179 and three different bottom edges in one row.
     
     align-items:start is gone with it. It was there to kill the dead white space
     that stretching unequal tiles created; equal columns mean equal frames, so
     stretching now just levels the bottom edge, which is the point. */
  .wall-row-2{display:grid;grid-template-columns:repeat(3,1fr);gap:34px;margin-top:34px}
  /* The 1.4fr 1fr 1fr template only works with three cards. With fewer, the
     remaining columns stay reserved and leave a visible hole beside them. */
  .wall-row-2--2{grid-template-columns:1fr 1fr}
  /* A single card must not become a full-width banner. It previously got
     grid-template-columns:1fr with a 21/9 frame, which turned one collection
     into a hero the height of the viewport. Cap it at a third of the row so it
     matches the cards above it. The split in collections.php now avoids this
     case entirely, but the rule has to be sane if it ever happens again. */
  .wall-row-2--1{grid-template-columns:minmax(0,calc(33.33% - 23px))}
  .wall-row-2--1 .ph{aspect-ratio:4/3}
  /* Top row with two tiles rather than three, when the split rebalances. */
  .wall-grid--2{grid-template-columns:repeat(2,1fr)}
  /* Half-width tiles are twice as wide, so the 3:4 portrait frame would make
     them 740px tall. Landscape ratio keeps a two-up row in proportion. */
  .wall-grid--2 .c-tall .ph{aspect-ratio:4/3}
  .wall-row-2 .ph{aspect-ratio:16/10}

  /* stories — soft-elevation rounded cards (was keyline boxes) */
  .stories{background:var(--mat)}
  .stories .head{display:flex;justify-content:space-between;align-items:end;gap:30px;flex-wrap:wrap}
  .story-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:30px;margin-top:52px}
  .story{background:#fff;border-radius:var(--r-card);overflow:hidden;box-shadow:var(--shadow);display:flex;flex-direction:column;transition:transform .3s,box-shadow .3s}
  .story:hover{transform:translateY(-5px);box-shadow:0 22px 44px -22px rgba(43,50,66,.45)}
  .story .ph{aspect-ratio:3/2;overflow:hidden}
  .story img{width:100%;height:100%;object-fit:cover}
  .story-body{padding:26px;display:flex;flex-direction:column;gap:12px;flex:1}
  .story h3{font-size:1.25rem}
  .story p{font-size:.94rem;flex:1;color:#3d4352}
  .story .fn{font-size:.8rem;font-style:italic;color:var(--muted)}
  .story a{color:var(--blue-deep);text-decoration:none;font-weight:500;font-size:.92rem;display:inline-flex;gap:8px;align-items:center}
  .story a .arr{transition:transform .25s}
  .story a:hover .arr{transform:translateX(5px)}

  /* drone */
  .dark{background:var(--slate);color:#dfe3ea}
  .drone .wrap{display:grid;grid-template-columns:1fr 1fr;gap:70px;align-items:center}
  .drone h2{color:#fff}
  .drone .lede{color:#aab3c6}
  .drone .matted{background:#333b4e;border-color:rgba(147,159,191,.35);padding:12px}
  .drone .matted .ph{aspect-ratio:4/5}
  .drone .plate{color:#c7cdd9}.drone .plate h3{color:#fff}
  .svc{list-style:none;display:flex;flex-direction:column;gap:14px;margin:30px 0 36px}
  .svc li{display:flex;justify-content:space-between;align-items:center;gap:20px;padding:16px 22px;border:1px solid rgba(147,159,191,.28);border-radius:999px;font-size:.98rem;transition:border-color .25s,background .25s}
  .svc li:hover{border-color:var(--blue);background:rgba(76,130,190,.1)}
  .svc strong{font-weight:400;font-family:var(--display);font-size:1.05rem;color:#fff}
  .svc span{color:var(--greyblue);font-size:.85rem;white-space:nowrap}
  .drone-note{font-size:.88rem;color:var(--greyblue);max-width:60ch;margin-top:26px}

  /* prints */
  .prints{background:var(--wall)}
  .prints-head{display:flex;justify-content:space-between;align-items:end;gap:32px;flex-wrap:wrap}
  .print-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:30px;margin-top:52px}
  .print-grid .matted{text-decoration:none}
  .print-grid .ph{aspect-ratio:1/1}
  .price-row{display:flex;justify-content:space-between;align-items:center;padding:10px 4px 2px}
  .price-row .price{font-size:.85rem;color:var(--blue-deep);font-weight:500}
  .chips{display:flex;gap:6px;padding:4px 4px 0;flex-wrap:wrap}
  .chip{font-size:.72rem;font-weight:400;border:1px solid rgba(91,92,16,.4);color:var(--olive);padding:3px 12px;border-radius:999px}
  .promo{margin-top:70px;background:var(--blue);color:#fff;display:grid;grid-template-columns:1fr 1.3fr;overflow:hidden;border-radius:var(--r-card);box-shadow:var(--shadow)}
  .promo img{width:100%;height:100%;object-fit:cover;min-height:300px}
  .promo-body{padding:48px 52px;display:flex;flex-direction:column;justify-content:center;gap:14px}
  .promo-body .badge{background:rgba(255,255,255,.16);color:#eaf1f9}
  .promo-body h3{font-size:1.7rem}
  .promo-body p{font-size:.98rem;color:#e7eef7}
  .promo .btn{align-self:flex-start;margin-top:10px}
  .promo .btn-ring-light:hover{background:#fff;color:var(--blue-deep)}

  /* contact — floating-label underline form (was boxed inputs) */
  .contact{background:var(--mat)}
  .contact .wrap{display:grid;grid-template-columns:1fr 1fr;gap:76px}
  .form{display:flex;flex-direction:column;gap:30px;margin-top:14px}
  .field{position:relative}
  .field input,.field textarea{width:100%;font-family:var(--body);font-size:1rem;font-weight:300;padding:20px 2px 8px;border:0;border-bottom:1.5px solid rgba(147,159,191,.6);background:transparent;color:var(--ink);border-radius:0}
  .field textarea{resize:vertical;min-height:96px}
  .field label{position:absolute;left:2px;top:20px;font-size:1rem;color:var(--muted);pointer-events:none;transition:all .2s ease}
  .field input:focus,.field textarea:focus{outline:none;border-bottom-color:var(--blue)}
  .field input:focus~label,.field input:not(:placeholder-shown)~label,
  .field textarea:focus~label,.field textarea:not(:placeholder-shown)~label{top:-2px;font-size:.78rem;color:var(--blue-deep);font-weight:500}
  .field-select label{position:static;display:block;font-size:.78rem;color:var(--blue-deep);font-weight:500;margin-bottom:6px}
  .field-select select{width:100%;font-family:var(--body);font-size:1rem;font-weight:300;padding:12px 2px;border:0;border-bottom:1.5px solid rgba(147,159,191,.6);background:transparent;color:var(--ink);border-radius:0}
  .field-select select:focus{outline:none;border-bottom-color:var(--blue)}
  .contact-list{list-style:none;display:flex;flex-direction:column;gap:20px;margin-top:28px}
  .contact-list strong{display:block;font-weight:500;font-size:.85rem;color:var(--blue-deep)}

  footer{background:var(--slate);color:#aab3c6;padding:56px 0 40px}
  .foot{display:flex;justify-content:space-between;align-items:center;gap:24px;flex-wrap:wrap}
  footer .mark{color:#fff}
  footer nav ul{gap:26px}
  footer nav a{color:#aab3c6}
  footer nav a:hover{color:#fff}
  footer nav a::after{background:#fff}
  .legal{margin-top:34px;font-size:.78rem;color:#79829a;text-align:center}

  .reveal{opacity:0;transform:translateY(26px);transition:opacity .7s ease,transform .7s ease}
  .reveal.in{opacity:1;transform:none}

  @media (max-width:1024px){
    .wall-grid{grid-template-columns:repeat(2,1fr)}
    .wall-row-2{grid-template-columns:1fr 1fr}
    .print-grid{grid-template-columns:repeat(2,1fr)}
    .story-grid{grid-template-columns:1fr 1fr}
    .drone .wrap{grid-template-columns:1fr}
  }
  @media (max-width:768px){
    section{padding:70px 0}
    nav ul{position:fixed;inset:59px 0 auto 0;background:var(--mat);flex-direction:column;gap:0;padding:10px 28px 24px;border-bottom:1px solid rgba(147,159,191,.3);display:none;align-items:flex-start}
    nav ul.open{display:flex}
    nav li{padding:12px 0}
    .menu-toggle{display:block}
    .meet .wrap,.contact .wrap,.promo,.story-grid,.wall-row-2{grid-template-columns:1fr}
    .wall-grid{grid-template-columns:1fr}
    .hero{min-height:80vh}
  }

/* ===== shared page chrome ===== */
.page-hero{position:relative;min-height:46vh;display:flex;align-items:flex-end;color:#eef1f4}
.page-hero::after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,rgba(43,50,66,.3),rgba(43,50,66,.62))}
.page-hero .ph-bg{position:absolute;inset:0;background-size:cover;background-position:center}
.page-hero .wrap{position:relative;z-index:2;padding-bottom:52px;width:100%}
.page-hero h1{font-family:var(--display);font-weight:400;font-size:clamp(2.2rem,5vw,3.6rem)}
.page-hero .crumb{font-size:.85rem;color:#c6ccd6;margin-bottom:10px}
.page-hero .crumb a{text-decoration:none}
.page-hero .crumb a:hover{color:#fff}

/* ===== galleries ===== */
.request-band{background:var(--slate);color:#dfe3ea;text-align:center;padding:16px 28px;font-size:.95rem}
.request-band a{color:#a9c4e4;font-weight:500;text-decoration:none}
.request-band a:hover{text-decoration:underline}
.filters{display:flex;gap:10px;flex-wrap:wrap;margin:44px 0 36px}
.filter{font-family:var(--body);font-size:.9rem;font-weight:400;padding:9px 22px;border-radius:999px;border:1.5px solid rgba(147,159,191,.6);background:transparent;color:var(--ink);cursor:pointer;transition:all .2s}
.filter:hover{border-color:var(--blue)}
.filter.active{background:var(--blue);border-color:var(--blue);color:#fff}
.collage{columns:3;column-gap:28px}
.collage .matted{break-inside:avoid;margin-bottom:28px;display:block;text-decoration:none}
.collage .ph{aspect-ratio:3/4;background:var(--wall)}
.collage .matted[data-ratio="landscape"] .ph{aspect-ratio:3/2}
.collage .matted[data-ratio="square"] .ph{aspect-ratio:1/1}
.collage .matted.hidden{display:none}
@media(max-width:1024px){.collage{columns:2}}
@media(max-width:640px){.collage{columns:1}}

/* ===== about ===== */
.prose{max-width:70ch;font-size:1.05rem}
.prose h2{font-size:clamp(1.5rem,3vw,2rem);margin:2.2em 0 .6em}
.prose p+p{margin-top:1em}
.pending{background:rgba(76,130,190,.08);border:1.5px dashed rgba(76,130,190,.5);border-radius:12px;padding:16px 20px;color:#3a668f;font-size:.95rem;margin:1em 0}
.pullquote{font-family:var(--display);font-size:clamp(1.3rem,2.6vw,1.8rem);line-height:1.4;color:var(--blue-deep);border-left:4px solid var(--blue);padding:6px 0 6px 26px;margin:2em 0}
.about-grid{display:grid;grid-template-columns:.85fr 1.15fr;gap:70px;align-items:start}
.about-grid .sticky{position:sticky;top:96px}
@media(max-width:900px){.about-grid{grid-template-columns:1fr}.about-grid .sticky{position:static}}
.gear{display:grid;grid-template-columns:repeat(3,1fr);gap:20px;margin-top:30px}
.gear .card{background:var(--mat);border:1px solid rgba(147,159,191,.4);border-radius:14px;padding:24px;font-size:.92rem}
.gear .card strong{display:block;font-weight:500;color:var(--blue-deep);margin-bottom:6px}
@media(max-width:800px){.gear{grid-template-columns:1fr}}

/* ===== drone ===== */
.steps{display:grid;grid-template-columns:repeat(3,1fr);gap:22px;margin-top:44px}
.step{background:var(--mat);border:1px solid rgba(147,159,191,.4);border-radius:16px;padding:30px 26px;box-shadow:var(--shadow)}
.step .n{font-family:var(--display);font-size:2rem;color:var(--blue)}
.step h3{font-size:1.15rem;margin:8px 0 8px}
.step p{font-size:.92rem;color:#3d4352}
@media(max-width:800px){.steps{grid-template-columns:1fr}}
.pkg-cards{display:grid;grid-template-columns:repeat(3,1fr);gap:24px;margin-top:44px}
.pkgc{background:#333b4e;border:1px solid rgba(147,159,191,.3);border-radius:16px;padding:34px 30px;display:flex;flex-direction:column;gap:14px;transition:transform .25s,border-color .25s}
.pkgc:hover{transform:translateY(-5px);border-color:var(--blue)}
.pkgc h3{color:#fff;font-size:1.3rem}
.pkgc .for{font-size:.82rem;color:var(--greyblue)}
.pkgc ul{list-style:none;display:flex;flex-direction:column;gap:9px;font-size:.93rem;color:#c9cdd8;flex:1}
.pkgc li{padding-left:20px;position:relative}
.pkgc li::before{content:"✦";position:absolute;left:0;top:2px;font-size:.7em;color:var(--blue)}
@media(max-width:900px){.pkg-cards{grid-template-columns:1fr}}

/* ===== shop / product ===== */
.shop-note{display:flex;gap:14px;align-items:center;background:var(--mat);border:1px solid rgba(147,159,191,.4);border-radius:14px;padding:18px 24px;font-size:.95rem;margin:40px 0}
.product-layout{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);gap:64px;align-items:start}
@media(max-width:900px){.product-layout{grid-template-columns:1fr}}
.thumbs{display:flex;gap:14px;margin-top:16px}
.thumbs button{width:76px;height:76px;border:1.5px solid rgba(147,159,191,.5);border-radius:10px;overflow:hidden;padding:0;cursor:pointer;background:none}
.thumbs button.active{border-color:var(--blue);box-shadow:0 0 0 2px rgba(76,130,190,.3)}
.thumbs img{width:100%;height:100%;object-fit:cover}
.p-title{font-size:clamp(1.7rem,3vw,2.3rem)}
.p-fn{font-size:.9rem;font-style:italic;color:var(--muted);margin:6px 0 18px}
.p-price{font-family:var(--display);font-size:1.6rem;color:var(--blue-deep);margin-bottom:26px}
.opt-label{font-weight:500;font-size:.85rem;color:var(--blue-deep);margin:22px 0 10px}
.mat-cards{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}
.mat-card{border:1.5px solid rgba(147,159,191,.5);border-radius:14px;padding:14px;cursor:pointer;text-align:center;transition:all .2s;background:var(--mat)}
.mat-card:hover{border-color:var(--blue)}
.mat-card.active{border-color:var(--blue);background:var(--blue-tint);box-shadow:0 0 0 2px rgba(76,130,190,.25)}
.mat-card strong{display:block;font-weight:500;font-size:.95rem}
.mat-card span{font-size:.76rem;color:#5b6275}
.size-row{display:flex;gap:10px;flex-wrap:wrap}
.size-pill{border:1.5px solid rgba(147,159,191,.5);border-radius:999px;padding:9px 20px;cursor:pointer;font-size:.9rem;background:var(--mat);transition:all .2s}
.size-pill:hover{border-color:var(--blue)}
.size-pill.active{background:var(--blue);border-color:var(--blue);color:#fff}
.add-row{display:flex;gap:14px;align-items:center;margin-top:30px}
.qty{display:inline-flex;border:1.5px solid rgba(147,159,191,.5);border-radius:999px;overflow:hidden}
.qty button{width:42px;height:46px;border:0;background:none;font-size:1.1rem;cursor:pointer}
.qty input{width:44px;border:0;text-align:center;font-family:var(--body);font-size:1rem;background:none}
.tabs{margin-top:56px;border-top:1px solid rgba(147,159,191,.4)}
.tab-btns{display:flex;gap:28px;margin:0;padding:0;list-style:none}
.tab-btns button{background:none;border:0;font-family:var(--body);font-size:.95rem;font-weight:400;padding:16px 2px;cursor:pointer;border-bottom:2.5px solid transparent;color:#5b6275}
.tab-btns button.active{color:var(--ink);border-color:var(--blue)}
.tab-panel{padding:24px 0 0;font-size:.97rem;max-width:70ch;display:none}
.tab-panel.active{display:block}

/* ===== story single ===== */
.story-hero{max-width:940px;margin:0 auto}
.story-meta{display:flex;gap:18px;align-items:center;justify-content:center;font-size:.88rem;color:#5b6275;margin:18px 0 8px;flex-wrap:wrap}
.story-title{text-align:center;font-size:clamp(2rem,4.5vw,3.1rem);max-width:20ch;margin:0 auto}
.story-body-prose{max-width:66ch;margin:44px auto 0;font-size:1.08rem}
.story-body-prose p+p{margin-top:1.2em}
.own-cta{max-width:940px;margin:70px auto 0;background:var(--slate);color:#dfe3ea;border-radius:var(--r-card);display:grid;grid-template-columns:.8fr 1.2fr;overflow:hidden;box-shadow:var(--shadow)}
.own-cta img{width:100%;height:100%;object-fit:cover;min-height:220px}
.own-cta .body{padding:38px 42px;display:flex;flex-direction:column;gap:12px;justify-content:center}
.own-cta h3{color:#fff;font-size:1.5rem}
@media(max-width:760px){.own-cta{grid-template-columns:1fr}}
.pn{display:flex;justify-content:space-between;max-width:940px;margin:60px auto 0;gap:20px;flex-wrap:wrap}

/* ===== WordPress integration layer =====
   Everything above this line is the approved prototype design, ported verbatim
   apart from four documented changes (contrast token, hero variable, nav active
   state, collage aspect reservation). Everything below exists only because the
   markup is now generated by WordPress rather than hand-written. */

/* Woo variation swatches.
   The real <select> stays in the DOM because WooCommerce's add-to-cart-variation.js
   binds to `.variations select` and matches variations from it. It is hidden from
   sight AND from assistive technology (aria-hidden is set on it by Woo's own
   markup path plus the wrapper below), because the swatch buttons carry the
   radiogroup semantics and are the control the user actually operates. */
.jrg-native{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.jrg-opt{margin:22px 0 0}
.jrg-opt-label{display:block;font-weight:500;font-size:.85rem;color:var(--blue-deep);margin:0 0 10px}

.jrg-swatch{font:inherit;cursor:pointer;background:var(--mat);text-align:left}
.jrg-swatch strong{display:block;font-weight:500}
.jrg-swatch:focus-visible{outline:3px solid var(--blue);outline-offset:3px}
.jrg-swatch.is-active.mat-card{border-color:var(--blue);background:var(--blue-tint);box-shadow:0 0 0 2px rgba(76,130,190,.25)}
.jrg-swatch.is-active.size-pill{background:var(--blue);border-color:var(--blue);color:#fff}
.jrg-swatch.is-disabled{opacity:.3;cursor:not-allowed;text-decoration:line-through}
.jrg-swatch.is-disabled:hover{border-color:inherit}

/* Woo's variable.php normally renders a table with a label column, which
   produced a duplicated "Material"/"Size" heading next to our own. The theme
   template drops the table; this catches any that slips through from a plugin. */
.variations_form table.variations th.label{display:none}
.woocommerce-variation-add-to-cart .button[disabled],
.woocommerce-variation-add-to-cart.woocommerce-variation-add-to-cart-disabled .button{
  opacity:.45;cursor:not-allowed}
.woocommerce-variation-price{margin:18px 0 6px}
.woocommerce-variation-price .price{font-family:var(--serif);font-size:1.6rem;color:var(--blue-deep)}
.reset_variations{display:none}

/* Woo notices, styled to the palette instead of Woo's defaults. */
.woocommerce-message,.woocommerce-info,.woocommerce-error{
  list-style:none;border-radius:var(--r-card);padding:16px 22px;margin:0 0 24px;
  background:var(--blue-tint);border:1px solid rgba(76,130,190,.35);font-size:.95rem}
.woocommerce-error{background:rgba(154,52,52,.08);border-color:rgba(154,52,52,.35)}

/* Prints available on request rather than in the cart. */
.request-print{display:flex;flex-direction:column;gap:12px;margin-top:30px;
  padding:24px;border:1.5px dashed rgba(76,130,190,.5);border-radius:var(--r-card);background:var(--blue-tint)}
.request-print p{font-size:.95rem;color:#3d4352;margin:0}

/* Screen-reader-only, matching core's class so plugins inherit it. */
.screen-reader-text{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.skip-link{position:absolute;left:-9999px;top:0;z-index:100;background:var(--mat);
  padding:12px 22px;border-radius:0 0 12px 0}
.skip-link:focus{left:0}

/* Staging-only placeholder for unwritten About sections. Hidden in production
   by a body class, so an unanswered questionnaire can never ship as visible
   "Awaiting Jeff's answer" text on the live site. */
body:not(.jrg-staging) .pending{display:none}

/* Pagination. */
.jrg-pagination{display:flex;gap:10px;justify-content:center;margin-top:56px;flex-wrap:wrap}
.jrg-pagination .page-numbers{display:inline-flex;align-items:center;justify-content:center;
  min-width:44px;height:44px;padding:0 14px;border-radius:999px;text-decoration:none;
  border:1.5px solid rgba(147,159,191,.5);font-size:.92rem}
.jrg-pagination .page-numbers:hover{border-color:var(--blue)}
.jrg-pagination .current{background:var(--blue);border-color:var(--blue);color:#fff}

/* Print-shop cards need the price to come from Woo, never from a template. */
.price-row .price del{opacity:.5;font-weight:400;margin-right:6px}
.price-row .price ins{text-decoration:none}

/* ===== WooCommerce layout reassertion =====
   woocommerce-layout.css is dequeued (see inc/assets.php), but plugins and the
   block styles can reintroduce the same float rules. These undo them explicitly
   so the grid is never fighting a float. */
.woocommerce div.product div.images,
.woocommerce div.product div.summary,
.product-layout > .images,
.product-layout > .summary{float:none;width:auto;margin:0}

.product-layout .woocommerce-product-gallery{width:100%!important;float:none}
.product-layout .flex-viewport{border-radius:var(--r-card);overflow:hidden}
.woocommerce-product-gallery__wrapper{margin:0}
.woocommerce-product-gallery img{border-radius:var(--r-card)}
.flex-control-thumbs{display:flex;gap:10px;list-style:none;margin:14px 0 0;padding:0}
.flex-control-thumbs li{width:76px}
.flex-control-thumbs img{border-radius:10px;cursor:pointer;opacity:.55;transition:opacity .2s}
.flex-control-thumbs img.flex-active,.flex-control-thumbs img:hover{opacity:1}

/* Tabs and related products sit below both columns, full width. */
.product-tabs{grid-column:1/-1;margin-top:56px}
.product-tabs .related,.product-tabs .upsells{margin-top:56px}
.product-tabs .related h2,.product-tabs .upsells h2{font-family:var(--serif);font-size:1.6rem;margin-bottom:26px}
.product-tabs ul.products{display:grid;grid-template-columns:repeat(4,1fr);gap:28px;list-style:none;padding:0;margin:0}
@media(max-width:900px){.product-tabs ul.products{grid-template-columns:repeat(2,1fr)}}
.product-tabs ul.products li{margin:0}

/* WooCommerce renders tabs as ul.tabs.wc-tabs > li > a, NOT as the prototype's
   .tab-btns > button. The prototype styles matched nothing, so the tabs rendered
   as bare browser defaults. Worse, Woo's <ul> carries the class "tabs" itself,
   which collided with our wrapper — hence .product-tabs above. */
.woocommerce-tabs{border-top:1px solid rgba(147,159,191,.4)}
.woocommerce-tabs ul.wc-tabs{display:flex;gap:28px;margin:0;padding:0;list-style:none;border:0}
.woocommerce-tabs ul.wc-tabs li{margin:0;padding:0;background:none;border:0}
.woocommerce-tabs ul.wc-tabs li::before,
.woocommerce-tabs ul.wc-tabs li::after{display:none}
.woocommerce-tabs ul.wc-tabs li a{display:block;font-family:var(--body);font-size:.95rem;font-weight:400;
  padding:16px 2px;text-decoration:none;border-bottom:2.5px solid transparent;color:#5b6275}
.woocommerce-tabs ul.wc-tabs li.active a,
.woocommerce-tabs ul.wc-tabs li a:hover{color:var(--ink);border-color:var(--blue)}
.woocommerce-tabs .wc-tab{padding:24px 0 0;font-size:.97rem;max-width:70ch}
.woocommerce-tabs .wc-tab h2{display:none}

/* Override woocommerce-general.css's default purple button. */
.woocommerce .button,
.woocommerce button.button,
.woocommerce a.button,
.woocommerce button.button.alt,
.single_add_to_cart_button{
  background:var(--blue)!important;color:#fff!important;border-radius:999px!important;
  font-family:var(--sans)!important;font-weight:500!important;padding:14px 30px!important;
  border:none!important;font-size:.95rem!important;line-height:1!important}
.woocommerce .button:hover,.woocommerce button.button:hover,.woocommerce a.button:hover{
  background:var(--blue-deep)!important}
.woocommerce .button:disabled,
.woocommerce button.button:disabled,
.single_add_to_cart_button.disabled{opacity:.4!important;cursor:not-allowed}
.woocommerce div.product form.cart .button{float:none}
.quantity input.qty{border:1.5px solid rgba(147,159,191,.5);border-radius:999px;padding:12px 8px;
  width:64px;text-align:center;font-family:var(--sans)}
.woocommerce div.product form.cart{display:flex;gap:12px;align-items:center;flex-wrap:wrap;margin-top:24px}
.woocommerce div.product form.cart .variations{display:block;width:100%}

/* ===== Custom print request =====
   Collapsed by default: it must be findable without competing with Add to cart,
   which is the action that matters on this page. */
.print-request{margin-top:30px;border-top:1px solid rgba(147,159,191,.4);padding-top:20px}
.print-request>summary{cursor:pointer;font-size:.92rem;color:var(--blue-deep);font-weight:500;
  list-style:none;padding:6px 0}
.print-request>summary::-webkit-details-marker{display:none}
.print-request>summary::before{content:"+ ";font-weight:400}
.print-request[open]>summary::before{content:"– "}
.print-request>summary:focus-visible{outline:3px solid var(--blue);outline-offset:3px}
.print-request__intro{font-size:.9rem;color:#3d4352;margin:10px 0 18px;max-width:56ch}
.print-request__grid{display:grid;grid-template-columns:1fr 1fr;gap:14px 18px}
@media(max-width:600px){.print-request__grid{grid-template-columns:1fr}}
.print-request__form p{margin:0 0 14px}
.print-request__form label{display:block;font-size:.8rem;color:var(--muted);margin-bottom:5px}
/* Every input type the forms actually use. This listed only text and email, so
   the phone field rendered as a bare native box — narrow, square, and obviously
   not part of the design. Enumerating types is fragile; :not() on the ones that
   must keep native styling is not. */
.print-request__form input:not([type=checkbox]):not([type=radio]):not([type=submit]),
.print-request__form select,
.print-request__form textarea{width:100%;padding:11px 13px;border:1.5px solid rgba(147,159,191,.5);
  border-radius:12px;font-family:var(--sans);font-size:.95rem;background:var(--mat);color:var(--ink)}
.print-request__form textarea{resize:vertical;min-height:120px}

/* Native select chrome does not match anything else on the page, so the arrow is
   drawn to match the palette. appearance:none needs its own arrow or the control
   loses its only affordance. */
.print-request__form select{
  appearance:none;-webkit-appearance:none;padding-right:42px;cursor:pointer;
  background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%235a6175' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 16px center;background-size:12px}
.print-request__form :focus-visible{outline:3px solid var(--blue);outline-offset:2px}
.print-request__hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.print-request__notice{padding:14px 18px;border-radius:var(--r-card);font-size:.94rem;margin:0 0 18px}
.print-request__notice--ok{background:var(--blue-tint);border:1px solid rgba(76,130,190,.35)}
.print-request__notice--error{background:rgba(154,52,52,.08);border:1px solid rgba(154,52,52,.35)}

/* ===== Story shop row, cause block, credential strip ===== */
.story-prints{margin-top:64px;padding-top:48px;border-top:1px solid rgba(147,159,191,.4)}
.story-prints h2{font-family:var(--serif);font-size:1.75rem;margin:12px 0 30px}

.cause{margin-top:56px}
.cause__inner{background:var(--blue-tint);border:1px solid rgba(76,130,190,.3);
  border-radius:var(--r-card);padding:34px 38px;max-width:64ch}
.cause__inner h2{font-family:var(--serif);font-size:1.5rem;margin:12px 0 14px}
.cause__inner p{font-size:.97rem;color:#3d4352;margin:0 0 14px}

/* Credential strip. Quiet on purpose — it is proof, not a boast, and it sits
   between the content and the footer where it reads as a signature. */
.seen-in{background:var(--wall);border-top:1px solid rgba(147,159,191,.35);padding:34px 0}
.seen-in__label{font-size:.72rem;letter-spacing:.22em;text-transform:uppercase;
  color:var(--muted);margin:0 0 16px}
.seen-in__list{display:flex;flex-wrap:wrap;gap:14px 40px;list-style:none;margin:0;padding:0}
.seen-in__list li{display:flex;flex-direction:column;gap:2px}
.seen-in__list strong{font-family:var(--serif);font-size:1.05rem;font-weight:400;color:var(--ink)}
.seen-in__list a{text-decoration:none}
.seen-in__list a:hover strong{color:var(--blue-deep)}
.seen-in__list span{font-size:.8rem;font-style:italic;color:var(--muted)}
.story-link{margin-top:26px;padding:14px 18px;background:var(--blue-tint);
  border-radius:var(--r-card);border:1px solid rgba(76,130,190,.28)}
.story-link a{color:var(--blue-deep);font-weight:500;text-decoration:none;font-size:.94rem}
.seen-in__logo{max-height:44px;width:auto;display:block}

/* ===== Services band, coverage line, credential strip ===== */

/* Services band. Reads as one row of five on desktop, wraps to a grid on
   tablet, and scrolls horizontally on a phone rather than becoming a five-screen
   stack that nobody reaches the bottom of. */
.services{background:var(--mat);padding:78px 0 84px;border-bottom:1px solid rgba(147,159,191,.35)}
.services .head{display:flex;justify-content:space-between;align-items:flex-end;gap:32px;margin-bottom:38px;flex-wrap:wrap}
.svc-grid{display:grid;grid-template-columns:repeat(5,1fr);gap:18px}
@media(max-width:1100px){.svc-grid{grid-template-columns:repeat(3,1fr)}}
@media(max-width:720px){
  .svc-grid{grid-template-columns:none;grid-auto-flow:column;grid-auto-columns:74%;
    overflow-x:auto;scroll-snap-type:x mandatory;padding-bottom:10px;
    margin:0 calc(var(--gutter,28px) * -1);
    padding-left:var(--gutter,28px);padding-right:var(--gutter,28px)}
  .svc-card{scroll-snap-align:start}
}
.svc-card{display:flex;flex-direction:column;gap:10px;padding:26px 22px 24px;
  background:var(--wall);border:1.5px solid rgba(147,159,191,.4);border-radius:var(--r-card);
  text-decoration:none;transition:all .25s}
.svc-card:hover{border-color:var(--blue);transform:translateY(-3px);
  box-shadow:0 14px 34px rgba(43,50,66,.1)}
.svc-card .ico{font-size:1.5rem;line-height:1}
.svc-card h3{font-family:var(--body);font-size:1.02rem;font-weight:500;color:var(--ink);margin:0}
.svc-card p{font-size:.87rem;color:var(--muted);margin:0;line-height:1.5}
.svc-card .go{margin-top:auto;padding-top:12px;font-size:.85rem;color:var(--blue-deep);font-weight:500}

/* Coverage line. Plain text, but it is the single most important string on the
   page for local search — and it is what a Chester County estate agent scans for
   before deciding whether to keep reading. */
.coverage{margin-top:34px;padding:18px 24px;background:var(--blue-tint);
  border-radius:var(--r-card);font-size:.92rem;color:#3d4352;
  display:flex;gap:14px;align-items:center;flex-wrap:wrap}
.coverage strong{color:var(--blue-deep);font-weight:500}

/* Two-audience hero: one CTA per intent, so nobody has to guess. */
.hero-cta .btn{min-width:210px;justify-content:center}

/* Credential strip lifted out of the footer and given a home. */
.seen-in--inline{background:transparent;border:0;padding:44px 0 0}
/* A collection with no image yet. Showing the gap beats filling it with an
   unrelated photograph, and it tells whoever can fix it that it needs fixing. */
.ph.awaiting{display:flex;align-items:center;justify-content:center;background:var(--wall);
  border:1.5px dashed rgba(147,159,191,.55)}
.ph.awaiting span{font-size:.85rem;color:var(--muted);text-align:center;line-height:1.6;font-style:italic}

/* Contact form. Shares the print-request styling so the two forms on the site
   do not look like they came from different places. */
.jrg-contact{margin:0}
.jrg-contact .print-request__grid{grid-template-columns:1fr 1fr}
@media(max-width:600px){.jrg-contact .print-request__grid{grid-template-columns:1fr}}
.contact .form{background:var(--mat);border-radius:var(--r-card);padding:34px 32px;
  border:1px solid rgba(147,159,191,.35)}
@media(max-width:700px){.contact .form{padding:26px 22px}}

/* ===== Missing-image placeholder =====
   Holds the space so the layout stays judgeable while content is still being
   gathered. Tonal, not a warning: a visitor should read it as a quiet empty
   frame, never as a broken one. `wp jrg missing` is what lists them. */
.jrg-placeholder{display:flex;align-items:center;justify-content:center;
  width:100%;height:100%;min-height:180px;background:var(--wall);
  color:rgba(90,97,117,.32)}
.ph .jrg-placeholder{position:absolute;inset:0;min-height:0}
.jrg-placeholder svg{width:clamp(34px,14%,58px);height:auto}
.dark .jrg-placeholder{background:rgba(255,255,255,.05);color:rgba(255,255,255,.22)}

/* Optional tip at checkout. */
.jrg-tip{margin:18px 0 24px;padding:18px 20px;background:var(--blue-tint);
  border:1px solid rgba(76,130,190,.3);border-radius:var(--r-card)}
.jrg-tip label{display:block;font-size:.9rem;color:var(--blue-deep);font-weight:500;margin-bottom:12px}
.jrg-tip__row{display:flex;gap:10px;flex-wrap:wrap}
.jrg-tip__btn{font:inherit;font-size:.9rem;padding:9px 18px;border-radius:999px;cursor:pointer;
  border:1.5px solid rgba(147,159,191,.55);background:var(--mat);color:var(--ink);transition:all .2s}
.jrg-tip__btn:hover{border-color:var(--blue)}
.jrg-tip__btn.is-active{background:var(--blue);border-color:var(--blue);color:#fff}

/* ==========================================================================
   Galleries — jrg_photo / jrg_gallery
   ========================================================================== */

.gallery-page .wrap{padding-top:52px;padding-bottom:88px}
.gallery-intro{max-width:62ch;margin:0 0 44px}
.gallery-venue{margin:-30px 0 44px;font-size:.95rem;letter-spacing:.04em;text-transform:uppercase;opacity:.62}
.gallery-empty{padding:72px 0;text-align:center;opacity:.6}

/* --- section view: a card per gallery ------------------------------------ */
.gallery-cards{display:grid;grid-template-columns:repeat(3,1fr);gap:34px}
/* Fewer than three cards must not leave reserved empty columns. The homepage
   band has two sections, a concert page has three siblings, a section archive
   has four — the same grid serves all of them, so the column count follows the
   card count instead of being fixed at three and hugging the left edge.
   :has() rather than a modifier class because this grid is rendered from four
   different templates; the base rule above is a sane fallback regardless. */
.gallery-cards:has(> :last-child:nth-child(2)){grid-template-columns:repeat(2,1fr)}
.gallery-cards:has(> :only-child){grid-template-columns:minmax(0,560px)}
.gallery-card{text-decoration:none;color:inherit;background:#fff;border-radius:var(--r-card);
  overflow:hidden;box-shadow:var(--shadow);display:flex;flex-direction:column;
  transition:transform .3s,box-shadow .3s}
.gallery-card:hover,.gallery-card:focus-visible{transform:translateY(-4px);box-shadow:0 18px 44px rgba(0,0,0,.16)}
.gallery-card__frame{display:block;aspect-ratio:4/3;overflow:hidden;background:#f2f1ee}
.gallery-card__img{width:100%;height:100%;object-fit:cover;display:block}
.gallery-card__body{padding:22px 24px 26px;display:flex;flex-direction:column;gap:5px}
.gallery-card__name{font-size:1.18rem;font-weight:600;line-height:1.25}
.gallery-card__count{font-size:.86rem;letter-spacing:.05em;text-transform:uppercase;opacity:.55}

/* --- gallery view: masonry wall ------------------------------------------
   CSS columns rather than a uniform grid, because this set runs from 3.6:1
   panoramas to 4:5 portraits inside one gallery and a fixed aspect ratio would
   either letterbox or crop through the subject. Columns also need no JS, so the
   wall is laid out before first paint. */
.photo-wall{column-count:3;column-gap:22px}
.photo{margin:0 0 22px;break-inside:avoid}
.photo__open{display:block;width:100%;padding:0;border:0;background:none;cursor:zoom-in;
  border-radius:10px;overflow:hidden;line-height:0}
.photo__open:focus-visible{outline:3px solid var(--blue,#1b3a5c);outline-offset:3px}
.photo__img{width:100%;height:auto;display:block;transition:opacity .25s,transform .45s}
.photo__open:hover .photo__img{opacity:.9;transform:scale(1.015)}

/* A panorama spans the whole wall: at one column wide it is a 60px-tall sliver. */
.photo--wide{column-span:all}

@media (max-width:1024px){
  .gallery-cards{grid-template-columns:repeat(2,1fr)}
  .photo-wall{column-count:2}
}
@media (max-width:640px){
  .gallery-cards{grid-template-columns:1fr}
  .photo-wall{column-count:1}
  .photo--wide{column-span:none}
}

/* --- commission prompt --------------------------------------------------- */
.gallery-cta{margin-top:72px;padding:40px;border-radius:var(--r-card);background:#f6f5f2;text-align:center}
.gallery-cta__note{margin:0 0 20px;opacity:.72}
.gallery-cta__action{margin:0;display:flex;gap:26px;align-items:center;justify-content:center;flex-wrap:wrap}
.gallery-cta__shop{font-size:.95rem;text-decoration:underline;text-underline-offset:3px}

/* --- lightbox -----------------------------------------------------------
   Built here rather than pulled in as a library: the whole behaviour is ~90
   lines, and a dependency for this would be a third-party script on every
   gallery page plus a licence to keep track of. */
.jrg-lb{position:fixed;inset:0;z-index:9999;display:none;
  background:rgba(14,14,16,.95);
  align-items:center;justify-content:center}
.jrg-lb[open],.jrg-lb.is-open{display:flex}
.jrg-lb__img{max-width:92vw;max-height:84vh;width:auto;height:auto;display:block;
  box-shadow:0 30px 80px rgba(0,0,0,.5)}
.jrg-lb__cap{position:absolute;left:0;right:0;bottom:22px;margin:0;padding:0 24px;
  text-align:center;color:#e9e7e3;font-size:.9rem;opacity:.8}
.jrg-lb__btn{position:absolute;border:0;background:rgba(255,255,255,.1);color:#fff;
  width:52px;height:52px;border-radius:50%;cursor:pointer;font-size:1.4rem;line-height:1;
  display:grid;place-items:center;transition:background .2s}
.jrg-lb__btn:hover{background:rgba(255,255,255,.22)}
.jrg-lb__btn:focus-visible{outline:3px solid #fff;outline-offset:2px}
.jrg-lb__close{top:22px;right:22px}
.jrg-lb__prev{left:22px;top:50%;transform:translateY(-50%)}
.jrg-lb__next{right:22px;top:50%;transform:translateY(-50%)}
.jrg-lb__count{position:absolute;top:30px;left:28px;color:#e9e7e3;font-size:.85rem;
  letter-spacing:.06em;opacity:.7}
body.jrg-lb-open{overflow:hidden}

@media (max-width:640px){
  .jrg-lb__prev{left:8px}
  .jrg-lb__next{right:8px}
  .jrg-lb__btn{width:44px;height:44px}
  .jrg-lb__img{max-width:96vw;max-height:76vh}
}

@media (prefers-reduced-motion:reduce){
  .photo__img,.gallery-card{transition:none}
  .photo__open:hover .photo__img{transform:none}
}

/* Sibling galleries listed under a portfolio page, so every gallery has a route
   to it from the navigation rather than only from a URL nobody links. */
.gallery-more{margin-top:76px}
.gallery-more__title{font-size:1.35rem;margin:0 0 28px;font-weight:600}

/* Homepage gallery band — the entry point to the not-for-sale gallery work.
   Sits directly under the shop collections and continues their grey field, so the
   two read as one "browse the work" zone before the white Stories section.

   Padding is 0 at the top ON PURPOSE. The generic `section{padding:100px 0}` plus
   a 96px top here stacked into 196px of empty grey between the collections wall
   and this heading. The collections section's own 100px bottom padding is the
   separation; adding more just doubles it.

   The background is set explicitly rather than left transparent. It was
   transparent, and only looked right because the BODY happens to be the same
   grey — so the band had no background of its own and would have broken the
   moment the page background changed. */
.galleries-band{background:var(--wall);padding:0 0 100px}
.galleries-band .gallery-cards{margin-top:52px}
@media (max-width:640px){ .galleries-band{padding-bottom:70px} }

/* Publication credit on a product page. Small and factual — it is a statement
   of fact about where the photograph ran, not a sales badge. */
.press-credit{display:inline-block;margin:0 0 22px;padding:7px 15px;border-radius:999px;
  background:rgba(27,58,92,.08);color:var(--blue,#1b3a5c);font-size:.84rem;
  letter-spacing:.03em;text-transform:uppercase}

/* --- gallery wall: masonry + load more -----------------------------------
   The base layout is CSS columns (above), which needs no JavaScript. site.js
   adds .is-masonry and switches to a grid whose rows are a 4px unit, giving each
   figure a span that matches its measured height. Columns rebalance the whole
   set whenever items are appended — every photograph already on screen jumps to
   a different column — where a grid fills in DOM order and leaves what is
   already placed exactly where it is. */
.photo-wall.is-masonry{column-count:auto;column-gap:normal;
  display:grid;grid-template-columns:repeat(3,1fr);grid-auto-rows:4px;column-gap:22px}
.photo-wall.is-masonry .photo{margin:0;break-inside:auto}
/* A panorama spans the full width in either layout. */
.photo-wall.is-masonry .photo--wide{grid-column:1/-1}

.photo-more{margin-top:46px;text-align:center}
.photo-more__btn{min-width:260px}
.photo-more__btn[disabled]{opacity:.6;cursor:default}
.photo-more__count{margin:16px 0 0;font-size:.88rem;opacity:.6}
.photo-more .page-numbers{margin:0 4px}

@media (max-width:1024px){
  .photo-wall.is-masonry{grid-template-columns:repeat(2,1fr)}
}
@media (max-width:640px){
  .photo-wall.is-masonry{grid-template-columns:1fr}
  .photo-wall.is-masonry .photo--wide{grid-column:auto}
  .photo-more__btn{min-width:0;width:100%}
}

/* =========================================================================
   MOBILE LAYER
   =========================================================================
   Everything below was added after auditing all nine templates at 360, 390
   and 414px in a real browser. It is deliberately one block at the end of the
   file rather than edits scattered through it: the responsive rules had grown
   to ten different breakpoints (600, 640, 700, 720, 760, 768, 800, 900, 1024,
   1100) added one at a time as somebody noticed a page was broken, which meant
   any component nobody happened to look at had no mobile rule at all. Keeping
   the corrections together makes the mobile behaviour reviewable in one place.

   Breakpoints used here, and only these:
     1024px  tablet
      768px  large phone / small tablet (the nav already collapses here)
      640px  phone
      420px  small phone
   ========================================================================= */

/* --- 1. Grid tracks that can actually shrink ------------------------------
   The shop overflowed its viewport by 65px at 360px wide. The grid box itself
   was the correct 304px, but its computed tracks were 160.8px and 206.6px —
   unequal, and 397px in total.

   The cause is that `repeat(2,1fr)` means `repeat(2,minmax(auto,1fr))`, and an
   `auto` minimum refuses to shrink a track below the intrinsic width of its
   content. One product title that could not wrap was enough to push its column
   to 206px and burst the container. Every `repeat(n,1fr)` grid in this
   stylesheet has the same latent fault; it only shows when some piece of
   content happens to be too wide, which is why it appeared on the shop and
   nowhere else.

   min-width:0 on the children lets the track win instead of the content. */
.print-grid > *,
.mat-cards > *,
.wall-grid > *,
.wall-row-2 > *,
.story-grid > *,
.gallery-cards > *,
.svc-grid > *,
.gear > *,
.steps > *,
.pkg-cards > *,
.collections .wall-grid > *,
.product-layout > *,
.print-request__grid > *,
.product-tabs ul.products > li { min-width: 0; }

/* Long unbroken strings — a filename, a URL pasted into a caption — overflow
   any container regardless of the above. */
.story-card h3, .matted .title, .gallery-card__name,
.prod-title, .price-row, .chip { overflow-wrap: anywhere; }

/* --- 2. Pagination, wherever it is rendered -------------------------------
   .jrg-pagination .page-numbers was already a correct 44px target, but three
   templates call paginate_links() directly without that wrapper
   (taxonomy-jrg_gallery.php, page-templates/galleries.php,
   page-templates/portfolio.php), so those rendered as bare 10x20px links —
   under half the 44px minimum, and the hardest thing on the site to tap.
   Styling .page-numbers itself covers every call site, present and future. */
.page-numbers{
  display:inline-flex; align-items:center; justify-content:center;
  min-width:44px; height:44px; padding:0 12px; margin:0 3px;
  border-radius:999px; text-decoration:none;
  border:1.5px solid rgba(147,159,191,.5); font-size:.92rem;
}
.page-numbers:hover{ border-color:var(--blue); }
.page-numbers.current{ background:var(--blue); border-color:var(--blue); color:#fff; }
.page-numbers.dots{ border:0; min-width:24px; }

/* --- 3. Layouts that never collapsed ------------------------------------- */
@media (max-width:768px){
  /* Four across, then two at 1024, then nothing. Two 137px cards with a title
     and a price is not a product listing, it is a thumbnail strip. */
  .product-tabs ul.products{ grid-template-columns:repeat(2,1fr); gap:18px; }
  .mat-cards{ gap:10px; }
}

@media (max-width:640px){
  .print-grid{ gap:18px; }
  .mat-cards{ grid-template-columns:repeat(3,1fr); }
  .gallery-cards{ grid-template-columns:1fr; }

  /* :has() sets this to two columns when a band holds exactly two cards.
     On a phone two cards side by side are 140px wide each. */
  .gallery-cards:has(> :last-child:nth-child(2)){ grid-template-columns:1fr; }

  .wall-grid, .wall-grid--2, .wall-row-2, .wall-row-2--1{ grid-template-columns:1fr; }
  .own-cta, .about-grid, .product-layout, .pkg-cards, .steps, .gear{ grid-template-columns:1fr; }

  .gallery-cta{ padding:28px 20px; }
  .gallery-cta__action{ gap:16px; flex-direction:column; }
}

@media (max-width:420px){
  /* 28px of gutter either side leaves 304px of content on a 360px phone. At
     this width the photographs are the point, so the gutter gives way.

     Set as a custom property, not as padding. The services carousel bleeds to
     the screen edge with a negative margin that has to match the gutter
     exactly; when this rule hardcoded padding:20px and the carousel still used
     -28px, the homepage gained precisely 8px of horizontal scroll — the
     difference between the two numbers. One value, declared once. */
  :root{ --gutter:20px; }
  .print-grid{ grid-template-columns:1fr; }
  .product-tabs ul.products{ grid-template-columns:1fr; }
}

/* --- 4. Touch targets -----------------------------------------------------
   The audit flagged every interactive element under 32px. Inline links inside
   a paragraph are left alone — padding them out would wreck the line box and
   they are not the problem. These are the standalone controls. */
@media (max-width:768px){
  /* Standalone controls get a real 44px box. */
  .gallery-cta__shop, .photo-more__btn, .page-numbers{
    display:inline-flex; align-items:center; justify-content:center; min-height:44px;
  }
  .menu-toggle{ min-width:44px; min-height:44px; }

  /* The card's closing call to action. It reads as a button and is tapped like
     one, so it gets button-sized even though it is marked up as a link. */
  .story .story-body > a{
    display:inline-flex; align-items:center; min-height:44px;
  }

  /* Links that sit inside a run of text — the "Facebook · Instagram" pair in
     the contact list, the breadcrumb — were only 20px tall, which is awkward
     with a thumb.

     The first attempt at this used padding-block, which grows the inline box
     without reserving room for it: the link's hit area silently expanded up
     over the <strong> label above it, so two tap targets overlapped. That is
     the fault this section exists to remove, not to introduce.

     inline-flex with a min-height makes the line box itself taller, so the
     neighbouring content moves out of the way and nothing collides. */
  .contact-list a, .crumb a{
    display:inline-flex; align-items:center; min-height:40px;
  }
}

/* --- 5. Type that was too small to read ----------------------------------
   .mark small is the wordmark's "PHOTOGRAPHY" line at .62rem — 9.9px. It is
   letter-spaced uppercase, which is the least legible combination there is at
   that size. Nudged up on small screens only, so the desktop lockup Jeff
   approved is untouched. */
@media (max-width:768px){
  .mark small{ font-size:.75rem; letter-spacing:.26em; }
  .chip, .seen-in__label{ font-size:.78rem; }
}

/* --- 6. Media that must never exceed its box ------------------------------ */
img, svg, video, iframe, table, pre{ max-width:100%; }
img, svg, video{ height:auto; }

/* --- 7. Two things that only read wrong at phone width -------------------- */
@media (max-width:640px){
  /* .shop-note is a flex row: a pill, then a sentence. Flex children shrink by
     default, so at 360px the pill was crushed into a three-line sliver reading
     "Simple / by / design" while the sentence took the rest. It is a label, not
     a column — it should sit above the text, at its natural width. */
  .shop-note{ flex-direction:column; align-items:flex-start; gap:10px; padding:16px 18px; }
  .shop-note .badge{ flex:0 0 auto; white-space:nowrap; }
}

@media (max-width:768px){
  /* The hero scrim is a three-stop gradient: .38 at the top, .12 at 45%, .55 at
     the bottom. That is tuned for the desktop composition, where 45% down is
     empty sky and the headline sits lower. On a phone the whole text block —
     headline, wordmark and the tagline, which wraps to four lines — lands in
     that .12 band, so light type sits on whatever the photograph happens to be
     doing there. On the Cape May hero that is a bright sunset and the tagline
     is close to unreadable.

     Deepened only below 768px, so the desktop treatment Jeff signed off is
     untouched. */
  .hero::after{
    background:linear-gradient(180deg,
      rgba(43,50,66,.52),
      rgba(43,50,66,.44) 45%,
      rgba(43,50,66,.66));
  }

  /* .5em of tracking on a phone turns the wordmark into three ragged lines. */
  .hero .sub{ letter-spacing:.28em; font-size:.95rem; }
  .hero .tag{ font-size:.98rem; margin:22px auto 30px; }
}
