/* ============================================================
   Portray -- the gallery wall
   Portraits hung in frames on a plaster wall. Frames sway.
   ============================================================ */

:root{
  --wall:#eeeae2;
  --ink:#171614;
  --ink-soft:#6d675e;
  --hair:rgba(23,22,20,.16);
  --accent:#8a7d6b;
  --focus:#3b6ea5;
  --pad:clamp(1rem,3.2vw,2.6rem);
  --ease:cubic-bezier(.22,.61,.36,1);
}

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;
  color:var(--ink);
  background-color:var(--wall);
  background-image:url("wall.jpg");
  background-repeat:repeat;
  background-size:430px 430px;
  font-family:-apple-system,BlinkMacSystemFont,"Helvetica Neue","Segoe UI",Roboto,Arial,sans-serif;
  font-size:16px;line-height:1.6;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
img{display:block;max-width:100%}
a{color:inherit;text-decoration:none}
:focus-visible{outline:2px solid var(--focus);outline-offset:4px}

/* light falling on the wall -- fixed, so the room stays lit as you scroll */
.wall-light{
  position:fixed;inset:0;z-index:0;pointer-events:none;
  background:
    radial-gradient(115% 70% at 50% -8%, rgba(255,255,255,.62), rgba(255,255,255,0) 58%),
    radial-gradient(90% 60% at 12% 8%, rgba(255,255,255,.30), rgba(255,255,255,0) 60%),
    radial-gradient(120% 90% at 50% 118%, rgba(58,48,36,.20), rgba(58,48,36,0) 62%);
}
.wall-vignette{
  position:fixed;inset:0;z-index:0;pointer-events:none;
  box-shadow:inset 0 0 clamp(80px,14vw,220px) rgba(52,43,32,.20),
             inset 0 0 clamp(30px,5vw,70px) rgba(52,43,32,.10);
}
.serif{font-family:"Cormorant Garamond",Georgia,"Times New Roman",serif;font-weight:500}

/* ---------------- top nav (reference-style micro type) ---------------- */
.topbar{
  /* above .mnav (80) so the Close control stays reachable while the menu is open */
  position:fixed;top:0;left:0;right:0;z-index:90;
  display:grid;grid-template-columns:1fr auto 1fr;align-items:start;gap:1rem;
  padding:1.15rem var(--pad);
  font-size:.72rem;letter-spacing:.14em;text-transform:uppercase;
}
.topbar .col-r{display:flex;gap:clamp(1.2rem,4vw,3.4rem);justify-content:flex-end}
.topbar .lbl{color:var(--ink);display:block}
.topbar .sub{
  display:block;margin-top:.28rem;
  font-family:"Cormorant Garamond",Georgia,serif;
  font-style:italic;text-transform:none;letter-spacing:.02em;
  font-size:.87rem;color:var(--ink-soft);
}
.topbar .sub a:hover{color:var(--ink)}
.topbar .mid{display:flex;gap:1.05rem;flex-wrap:wrap;justify-content:center}
.topbar .mid a{color:var(--ink-soft);transition:color .3s var(--ease)}
.topbar .mid a:hover{color:var(--ink)}

/* ---------------- hanging system ---------------- */
/* .hang pivots about the nail: transform-origin sits at the nail head.
   The wall is still by default. The only movement is a barely
   perceptible lean on hover and one short settle on click -- both
   far below the threshold where they would compete with the work. */
.hang{
  position:relative;
  transform-origin:50% 3px;
  padding-top:var(--wire,58px);
  transition:transform 220ms var(--ease);
}
.hang:hover,
.hang:focus-within{ transform:rotate(0.16deg); }

/* one short settle when a frame is opened -- an acknowledgement, not a swing */
@keyframes settle{
  0%   { transform:rotate(0deg) }
  28%  { transform:rotate(-0.30deg) }
  58%  { transform:rotate(0.12deg) }
  82%  { transform:rotate(-0.04deg) }
  100% { transform:rotate(0deg) }
}
.hang.ack{ animation:settle 460ms var(--ease) 1 both; }
.hang .wire{
  position:absolute;top:0;left:0;width:100%;height:var(--wire,58px);
  overflow:visible;pointer-events:none;
}
.hang .wire .cord{fill:none;stroke:#5f584e;stroke-width:1.15;opacity:.9}
.hang .wire .cord-hl{fill:none;stroke:rgba(255,255,255,.5);stroke-width:.55;transform:translate(-.6px,-.6px)}
.hang .wire .nail{fill:#332e27}
.hang .wire .nail-hl{fill:rgba(255,255,255,.5)}
.hang .wire .nail-sh{fill:rgba(60,48,34,.32)}

/* frame moulding */
.frame{
  position:relative;display:block;width:100%;padding:0;border:0;cursor:pointer;
  background:
    linear-gradient(145deg,#3a342c 0%,#22201c 38%,#151311 62%,#2b2721 100%);
  padding:clamp(7px,.75vw,11px);          /* the moulding width */
  border-radius:1px;
  box-shadow:
    /* moulding bevel */
    inset 0 1px 0 rgba(255,255,255,.22),
    inset 0 -1px 0 rgba(0,0,0,.55),
    inset 1px 0 0 rgba(255,255,255,.10),
    inset -1px 0 0 rgba(0,0,0,.45),
    /* contact + ambient shadow cast on the wall (light from upper-left) */
    2px 3px 3px rgba(46,36,24,.40),
    5px 8px 12px rgba(46,36,24,.30),
    10px 18px 28px rgba(46,36,24,.26),
    18px 36px 56px rgba(46,36,24,.22),
    30px 62px 92px rgba(46,36,24,.14);
  transition:box-shadow .5s var(--ease);
}
.frame:hover{
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.24),
    inset 0 -1px 0 rgba(0,0,0,.55),
    inset 1px 0 0 rgba(255,255,255,.10),
    inset -1px 0 0 rgba(0,0,0,.45),
    3px 4px 5px rgba(46,36,24,.42),
    7px 11px 18px rgba(46,36,24,.32),
    14px 26px 40px rgba(46,36,24,.28),
    26px 50px 76px rgba(46,36,24,.24),
    42px 82px 124px rgba(46,36,24,.16);
}

/* the mount / mat board */
.mat{
  position:relative;
  background:linear-gradient(160deg,#fbfaf7 0%,#f3f1ec 55%,#eae7e0 100%);
  padding:clamp(12px,2.1vw,30px);
  padding-bottom:clamp(20px,3.3vw,46px);   /* traditional weighted bottom margin */
  box-shadow:inset 0 1px 2px rgba(0,0,0,.16);
}
/* bevelled cut of the mat opening */
.opening{
  position:relative;
  box-shadow:
    0 0 0 1px rgba(120,112,98,.35),
    0 1px 0 1px rgba(255,255,255,.9),
    inset 0 1px 3px rgba(0,0,0,.30);
}
.opening img{
  width:100%;height:auto;display:block;
  opacity:0;transform:scale(1.015);
  transition:opacity 1.1s var(--ease),transform 1.3s var(--ease);
}
.opening img.loaded{opacity:1;transform:scale(1)}

/* glass: a faint diagonal reflection across the whole frame */
.glass{
  position:absolute;inset:0;pointer-events:none;
  background:
    linear-gradient(114deg,
      rgba(255,255,255,.20) 0%,
      rgba(255,255,255,.09) 16%,
      rgba(255,255,255,.015) 30%,
      rgba(255,255,255,0) 44%),
    linear-gradient(292deg,
      rgba(255,255,255,.10) 0%,
      rgba(255,255,255,.02) 14%,
      rgba(255,255,255,0) 26%);
  mix-blend-mode:screen;
}

/* museum label under each frame.
   On touch there is no hover, so the label is simply always shown;
   pointer devices keep the quieter reveal. */
.label{
  margin:.85rem auto 0;text-align:center;
  font-size:.58rem;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-soft);
  opacity:.85;
  transition:opacity .5s var(--ease),transform .5s var(--ease);
}
@media (hover:hover) and (pointer:fine){
  .label{opacity:0;transform:translateY(3px)}
  .hang:hover .label,
  .hang:focus-within .label{opacity:1;transform:translateY(0)}
}

/* ---------------- hero ---------------- */
.hero{
  position:relative;z-index:2;
  height:100svh;min-height:640px;
  display:flex;align-items:center;justify-content:center;
  padding:clamp(3rem,6vh,4.5rem) var(--pad) clamp(7.5rem,19vh,12.5rem);
}
.hero .hang{width:min(330px,26vw,29vh);--wire:clamp(42px,6.5vh,78px)}
.wordmark{
  position:absolute;left:0;right:0;bottom:clamp(1.1rem,4.5vh,3rem);
  z-index:5;text-align:center;pointer-events:none;
}
.wordmark h1{
  margin:0;font-size:clamp(3.4rem,15vw,15rem);line-height:.84;
  letter-spacing:.005em;font-weight:500;
}
.wordmark .tagline{
  margin:.55rem 0 0;font-size:clamp(.95rem,2.1vw,1.5rem);
  font-style:italic;color:var(--ink-soft)
}
/* service + location line -- quiet, but a real heading for search */
.wordmark .service{
  margin:1.05rem auto 0;max-width:min(100%,34rem);
  font-family:inherit;font-weight:400;
  font-size:clamp(.53rem,1.02vw,.66rem);
  letter-spacing:.155em;text-transform:uppercase;line-height:1.85;
  color:var(--ink-soft);text-wrap:balance;
}
.wordmark .service .dash{opacity:.55;padding:0 .15em}
.hero .cue{
  position:absolute;bottom:1.5rem;left:50%;transform:translateX(-50%);
  font-size:.58rem;letter-spacing:.24em;text-transform:uppercase;color:var(--ink-soft);
  display:flex;flex-direction:column;align-items:center;gap:.6rem;
}
.hero .cue i{display:block;width:1px;height:34px;background:linear-gradient(var(--ink-soft),transparent);
  animation:drop 2.8s var(--ease) infinite}
@keyframes drop{0%,100%{transform:scaleY(.4);transform-origin:top;opacity:.25}50%{transform:scaleY(1);opacity:.7}}

/* ---------------- the wall of frames (salon hang) ---------------- */
.wall{
  position:relative;z-index:2;
  max-width:1560px;margin:0 auto;
  padding:clamp(3rem,9vh,8rem) var(--pad) clamp(4rem,10vh,9rem);
  display:flex;flex-wrap:wrap;justify-content:center;align-items:flex-start;
  gap:clamp(2.2rem,4.6vw,5.2rem) clamp(2rem,4vw,4.6rem);
}
.wall .hang{width:var(--w,24%);margin-top:var(--drop,0px)}

.section-mark{
  position:relative;z-index:2;text-align:center;
  padding-top:clamp(2rem,6vh,4rem);
  font-size:.6rem;letter-spacing:.26em;text-transform:uppercase;color:var(--ink-soft);
}

/* ---------------- wall-mounted text panel (about) ---------------- */
.panel-wrap{position:relative;z-index:2;display:flex;justify-content:center;padding:0 var(--pad) clamp(4rem,10vh,8rem)}
.panel{
  max-width:980px;width:100%;
  background:linear-gradient(160deg,#fcfbf8,#f2f0ea);
  padding:clamp(2rem,4.5vw,3.4rem);
  box-shadow:
    0 1px 2px rgba(48,38,26,.26),
    0 6px 12px rgba(48,38,26,.18),
    0 18px 34px rgba(48,38,26,.16),
    0 40px 70px rgba(48,38,26,.10);
}
/* editorial two-column: the photographer's portrait sets the section, bio runs beside it */
.panel{
  display:grid;
  grid-template-columns:minmax(0,.86fr) minmax(0,1.14fr);
  gap:clamp(1.5rem,3.2vw,2.8rem);
  align-items:start;
}
.portrait-of{margin:0}
.portrait-of img{
  width:100%;height:auto;display:block;
  background:var(--canvas-2);
  box-shadow:
    0 0 0 1px rgba(120,112,98,.22),
    0 1px 2px rgba(46,36,24,.16),
    0 6px 14px rgba(46,36,24,.12),
    0 16px 30px rgba(46,36,24,.10);
}
.portrait-of figcaption{
  margin-top:.75rem;
  font-size:.58rem;letter-spacing:.16em;text-transform:uppercase;
  line-height:1.7;color:var(--ink-soft);
}
.panel-body{min-width:0}
.panel h2{margin:0 0 1.1rem;font-size:clamp(1.7rem,3.6vw,2.5rem);line-height:1.05;font-weight:500}
.panel .lead{margin:0 0 1.1rem;font-size:1.06rem}
.panel p{margin:0 0 1rem;color:var(--ink-soft);font-size:.98rem}
.panel .meta{
  margin-top:1.8rem;padding-top:1.4rem;border-top:1px solid var(--hair);
  display:flex;flex-wrap:wrap;gap:.5rem 2.2rem;font-size:.93rem;
}
.panel .meta .k{display:block;font-size:.58rem;letter-spacing:.18em;text-transform:uppercase;color:var(--ink-soft);margin-bottom:.15rem}
.panel .meta a{border-bottom:1px solid var(--hair);transition:border-color .3s var(--ease)}
.panel .meta a:hover{border-color:var(--accent);color:var(--accent)}
.panel .note{margin-top:1.4rem;font-size:.76rem;color:var(--ink-soft)}

/* ---------------- footer ---------------- */
.site-footer{
  position:relative;z-index:2;
  border-top:1px solid var(--hair);
  margin:0 var(--pad);padding:2.2rem 0 2.6rem;
  display:flex;flex-wrap:wrap;gap:.8rem 2rem;align-items:baseline;justify-content:space-between;
  font-size:.6rem;letter-spacing:.16em;text-transform:uppercase;color:var(--ink-soft);
}
.site-footer .mark{font-size:1.15rem;letter-spacing:.02em;text-transform:none;color:var(--ink)}

/* ---------------- lightbox ---------------- */
.lb{
  position:fixed;inset:0;z-index:100;display:flex;align-items:center;justify-content:center;
  background:rgba(18,16,13,.93);
  opacity:0;visibility:hidden;transition:opacity .45s var(--ease),visibility .45s var(--ease);
}
.lb.open{opacity:1;visibility:visible}
.lb__img{max-width:90vw;max-height:84vh;box-shadow:0 40px 90px rgba(0,0,0,.6);
  opacity:0;transform:scale(.985);transition:opacity .5s var(--ease),transform .5s var(--ease)}
.lb.open .lb__img.ready{opacity:1;transform:scale(1)}
.lb__btn{position:absolute;top:50%;transform:translateY(-50%);width:58px;height:58px;border:0;background:none;
  color:#fff;opacity:.55;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:opacity .25s var(--ease)}
.lb__btn:hover{opacity:1}
.lb__btn svg{width:26px;height:26px}
.lb__prev{left:.4rem}.lb__next{right:.4rem}
.lb__close{position:absolute;top:1rem;right:1.2rem;width:44px;height:44px;border:0;background:none;color:#fff;opacity:.55;cursor:pointer}
.lb__close:hover{opacity:1}
.lb__cap{position:absolute;bottom:1.2rem;left:0;right:0;text-align:center;color:#fff;opacity:.5;
  font-size:.6rem;letter-spacing:.22em;text-transform:uppercase}

/* ---------------- touch targets ----------------
   The small letter-spaced links are visually correct but only ~15px tall.
   Each gets an invisible 44px hit area centred on it, which satisfies the
   minimum touch size without moving anything on screen. */
.topbar .mid a,
.topbar .sub a,
.panel .meta a{position:relative}
.topbar .mid a::after,
.topbar .sub a::after,
.panel .meta a::after{
  content:"";position:absolute;
  left:-.45rem;right:-.45rem;top:50%;transform:translateY(-50%);
  height:44px;
}

/* ---------------- phone navigation ----------------
   Hidden on pointer devices; on phones it replaces the three-column bar,
   which cannot hold readable type at 390px. */
.nav-toggle{
  display:none;
  align-items:center;min-height:46px;
  border:0;background:none;padding:0 0 0 1.2rem;margin:-11px 0;
  font:inherit;color:var(--ink);letter-spacing:inherit;text-transform:inherit;
  cursor:pointer;
}
.mnav{
  position:fixed;inset:0;z-index:80;
  background-color:var(--wall);
  background-image:url("wall.jpg");
  background-size:430px 430px;
  opacity:0;visibility:hidden;                 /* visibility:hidden also removes the links from the tab order */
  transition:opacity .3s var(--ease),visibility .3s var(--ease);
}
.mnav.open{opacity:1;visibility:visible}
.mnav__inner{
  position:absolute;inset:0;
  display:flex;flex-direction:column;justify-content:center;
  padding:6rem var(--pad) 3rem;
}
.mnav__link{
  display:flex;align-items:center;min-height:60px;
  font-size:2.1rem;line-height:1.1;color:var(--ink);
  border-bottom:1px solid var(--hair);
}
.mnav__link:first-child{border-top:1px solid var(--hair)}
.mnav__meta{
  margin-top:2.4rem;display:flex;flex-direction:column;gap:.15rem;
}
.mnav__meta .k{
  font-size:.66rem;letter-spacing:.18em;text-transform:uppercase;color:var(--ink-soft);
  margin-top:1.1rem;
}
.mnav__meta .k:first-child{margin-top:0}
.mnav__meta a{
  display:flex;align-items:center;min-height:44px;
  font-size:1.02rem;color:var(--ink);
}
body.nav-open{overflow:hidden}

/* ---------------- responsive ---------------- */
@media (max-width:1100px){
  .wall .hang{width:var(--w-md,31%)}
  .hero .hang{width:min(330px,44vw,29vh)}
}

/* type floor for every small screen, tablets included.
   The editorial micro-type is right on a large display and unreadable on a
   small one; below 1000px nothing is allowed under 11px. */
@media (max-width:1000px){
  .label{font-size:.7rem;letter-spacing:.14em}
  .wordmark .service{font-size:.72rem;letter-spacing:.13em}
  .section-mark{font-size:.72rem;letter-spacing:.2em}
  .site-footer{font-size:.7rem;letter-spacing:.14em}
  .portrait-of figcaption{font-size:.72rem;letter-spacing:.13em}
  .panel .meta .k{font-size:.7rem;letter-spacing:.16em}
  .lb__cap{font-size:.7rem;letter-spacing:.18em}
}

/* ---------------- phones ----------------
   Not a scaled desktop: the bar becomes one tap target, the salon hang
   becomes a single readable column, and every piece of type is raised to
   a size that does not need zooming. Reference viewport 390 x 844. */
@media (max-width:720px){
  :root{--pad:1.25rem}

  /* --- top bar --- */
  .topbar{
    grid-template-columns:1fr auto;align-items:center;gap:1rem;
    font-size:.7rem;letter-spacing:.16em;padding:1rem var(--pad);
  }
  /* a soft wash so the bar stays legible over frames and over the white
     About panel as they scroll under it */
  .topbar::before{
    content:"";position:absolute;inset:0 0 -16px;z-index:-1;pointer-events:none;
    background:linear-gradient(rgba(238,234,226,.90) 52%,rgba(238,234,226,.58) 78%,rgba(238,234,226,0));
    -webkit-backdrop-filter:blur(7px);backdrop-filter:blur(7px);
    -webkit-mask-image:linear-gradient(#000 62%,rgba(0,0,0,.5) 82%,transparent);
    mask-image:linear-gradient(#000 62%,rgba(0,0,0,.5) 82%,transparent);
  }
  /* the hero frame's label would sit directly on top of the wordmark */
  .hero .label{display:none}
  .topbar .col-r,
  .topbar .mid,
  .topbar .col-l .sub{display:none}
  .nav-toggle{display:flex}

  /* --- hero ---
     On a phone the wordmark is NOT absolutely positioned. Safari's toolbars
     make the real viewport shorter than any emulator reports, so reserving
     space for the wordmark with padding-bottom put it on top of the frame on
     a physical handset. Laying the hero out as a flow column instead means
     the gap is guaranteed at any viewport height, with or without browser UI. */
  .hero{
    height:auto;min-height:100svh;
    flex-direction:column;justify-content:center;
    gap:clamp(1.5rem,4vh,2.4rem);
    padding:5.5rem var(--pad) 3rem;
  }
  .hero .hang{width:min(300px,62vw,31vh);--wire:clamp(34px,4.5vh,52px)}
  .wordmark{position:static;bottom:auto}
  .wordmark h1{font-size:clamp(3.4rem,16vw,5.5rem)}
  .wordmark .tagline{margin-top:.5rem;font-size:1.12rem}
  .wordmark .service{
    margin-top:1.15rem;max-width:20rem;
    font-size:.72rem;letter-spacing:.13em;line-height:1.75;
  }

  /* --- the wall: one column, frames large enough to actually read --- */
  .section-mark{
    padding-top:clamp(2.4rem,7vh,3.6rem);
    font-size:.72rem;letter-spacing:.2em;
  }
  .wall{
    flex-direction:column;align-items:center;
    padding:clamp(2.6rem,7vh,4rem) var(--pad) clamp(3rem,8vh,5rem);
    gap:clamp(2.6rem,8vw,3.6rem);
  }
  /* widths cycle so the column keeps a little of the salon rhythm
     without ever dropping the picture below a readable size */
  .wall .hang{width:88%;margin-top:0;padding-top:40px}
  .wall .hang:nth-child(3n+2){width:78%}
  .wall .hang:nth-child(3n+3){width:84%}
  .wall .hang .wire{height:40px}
  .label{margin-top:.9rem;font-size:.7rem;letter-spacing:.14em;opacity:1}

  /* --- about panel --- */
  .panel{grid-template-columns:1fr;gap:1.6rem;padding:1.6rem 1.4rem 1.9rem}
  .panel h2{font-size:2rem;margin-bottom:1rem}
  .panel .lead{font-size:1.14rem;line-height:1.55}
  .panel p{font-size:1.02rem;line-height:1.68}
  .panel .meta{flex-direction:column;gap:1.15rem;font-size:1.02rem}

  /* --- footer --- */
  .site-footer{
    flex-direction:column;gap:.7rem;align-items:flex-start;
    padding:2.2rem 0 2.8rem;font-size:.7rem;letter-spacing:.14em;line-height:1.7;
  }
  .site-footer .mark{font-size:1.5rem}

  /* --- lightbox --- */
  .lb__img{max-width:94vw;max-height:76vh}
  .lb__btn{width:52px;height:52px}
  .lb__prev{left:0}.lb__next{right:0}
  .lb__close{top:.6rem;right:.6rem;width:48px;height:48px}
  .lb__cap{bottom:1.5rem;font-size:.7rem;letter-spacing:.18em}
}

/* very narrow phones (320-360) */
@media (max-width:380px){
  .wall .hang,
  .wall .hang:nth-child(3n+2),
  .wall .hang:nth-child(3n+3){width:92%}
  .wordmark h1{font-size:3.4rem}
  .mnav__link{font-size:1.85rem;min-height:56px}
}

/* short landscape phones: the hero must not force a 640px scroll */
@media (max-width:900px) and (max-height:520px){
  .hero{min-height:0;height:auto;padding:5rem var(--pad) 3rem}
  .hero .hang{width:min(200px,26vw,52vh)}
  .wordmark{position:static;margin-top:1.6rem}
}

/* ---------------- reduced motion ----------------
   Frames hang perfectly still -- no sway, no drift, nothing that
   moves position. Quiet cross-fades are kept, since they carry
   meaning (an image arriving, a label appearing) without motion. */
@media (prefers-reduced-motion:reduce){
  .hang,.hang:hover,.hang:focus-within,.hang.ack{
    transform:none!important;animation:none!important;transition:none!important}
  .opening img{opacity:1!important;transform:none!important;transition:none}
  .frame,.frame:hover{transition:box-shadow .18s linear}
  .label{transform:none!important;transition:opacity .18s linear}
  .hang:hover .label{transform:none!important}
  .lb,.mnav{transition:opacity .18s linear,visibility .18s linear}
  .lb__img,.lb.open .lb__img.ready{transform:none!important;transition:opacity .18s linear}
  .site-header,.topbar{transition:none}
  *{animation:none!important}
}
