:root{
  --ink:#25211c;
  --ink-soft:#5c5347;
  --ink-faint:#8b8175;
  --paper:#faf7f2;
  --paper-2:#f2ece2;
  --line:#e0d7c8;
  --gold:#9a7b3f;
  --gold-soft:#c9ae76;
  --white:#fffdfa;
  --radius:4px;
  --serif:"Cormorant Garamond",Georgia,"Times New Roman",serif;
  --sans:"Inter",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
}
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;background:var(--paper);color:var(--ink);
  font-family:var(--sans);font-size:16px;line-height:1.7;font-weight:400;
  -webkit-font-smoothing:antialiased;
}
img{max-width:100%;display:block}

.skip{position:absolute;left:-9999px}
.skip:focus{left:1rem;top:1rem;background:var(--white);padding:.6rem 1rem;z-index:99}

/* ---------- hero ---------- */
.hero{
  text-align:center;padding:clamp(3rem,8vw,5.5rem) 1.25rem clamp(2rem,5vw,3rem);
  background:linear-gradient(180deg,var(--paper-2) 0%,var(--paper) 100%);
  border-bottom:1px solid var(--line);
}
.hero-photo-wrap{
  width:clamp(150px,34vw,215px);aspect-ratio:1;margin:0 auto 1.75rem;
  border-radius:50%;overflow:hidden;background:var(--paper-2);
  border:1px solid var(--line);
  box-shadow:0 1px 2px rgba(37,33,28,.05),0 12px 34px -14px rgba(37,33,28,.28);
}
.hero-photo{width:100%;height:100%;object-fit:cover}
.hero-photo-wrap.is-empty{display:none}
.kicker{
  font-family:var(--sans);font-size:.7rem;font-weight:500;
  letter-spacing:.22em;text-transform:uppercase;color:var(--gold);
  margin:0 0 .85rem;
}
h1{
  font-family:var(--serif);font-weight:500;
  font-size:clamp(2.4rem,7vw,4rem);line-height:1.08;
  margin:0;letter-spacing:.005em;
}
.nickname{
  font-family:var(--serif);font-style:italic;font-size:1.2rem;
  color:var(--ink-soft);margin:.55rem 0 0;
}
.dates{
  font-family:var(--sans);font-size:.82rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-faint);margin:1.15rem 0 0;
}
.dates .dash{color:var(--gold-soft);margin:0 .35em}
.epitaph{
  font-family:var(--serif);font-size:clamp(1.1rem,2.6vw,1.4rem);
  font-style:italic;color:var(--ink-soft);
  max-width:34rem;margin:1.9rem auto 0;line-height:1.55;
}
.epitaph:empty{display:none}

/* ---------- tabs ---------- */
.tabs{
  position:sticky;top:0;z-index:20;
  display:flex;gap:.25rem;justify-content:center;flex-wrap:wrap;
  padding:.55rem .75rem;
  background:rgba(250,247,242,.93);
  backdrop-filter:saturate(180%) blur(10px);
  border-bottom:1px solid var(--line);
}
.tab{
  appearance:none;border:0;background:transparent;cursor:pointer;
  font-family:var(--sans);font-size:.78rem;font-weight:500;
  letter-spacing:.1em;text-transform:uppercase;color:var(--ink-faint);
  padding:.6rem .85rem;border-radius:var(--radius);
  transition:color .18s ease,background .18s ease;
}
.tab:hover{color:var(--ink)}
.tab.is-active{color:var(--ink);background:var(--paper-2)}
.tab:focus-visible{outline:2px solid var(--gold);outline-offset:2px}

/* ---------- panels ---------- */
main{max-width:60rem;margin:0 auto;padding:clamp(2.25rem,6vw,4rem) 1.25rem 4rem}
.panel[hidden]{display:none}
.panel-head{text-align:center;margin-bottom:2.25rem}
h2{
  font-family:var(--serif);font-weight:500;
  font-size:clamp(1.7rem,4.5vw,2.4rem);margin:0;line-height:1.2;
}
.lede{color:var(--ink-soft);margin:.6rem auto 0;max-width:36rem;font-size:.98rem}

/* ---------- service card ---------- */
.service-card{
  background:var(--white);border:1px solid var(--line);
  border-radius:var(--radius);padding:1.5rem;margin-bottom:2rem;
}
.service-card dl{margin:0;display:grid;gap:1rem;
  grid-template-columns:repeat(auto-fit,minmax(150px,1fr))}
.service-card dt{
  font-size:.68rem;letter-spacing:.16em;text-transform:uppercase;
  color:var(--gold);margin-bottom:.3rem;
}
.service-card dd{margin:0;font-size:.95rem;color:var(--ink)}

/* ---------- documents ---------- */
.doc-frame{
  width:100%;height:min(78vh,900px);border:1px solid var(--line);
  border-radius:var(--radius);background:var(--white);display:block;
}
.doc-actions{
  display:flex;gap:.7rem;justify-content:center;flex-wrap:wrap;
  margin-top:1.1rem;
}
.btn,.btn-ghost{
  display:inline-block;font-family:var(--sans);font-size:.78rem;font-weight:500;
  letter-spacing:.1em;text-transform:uppercase;
  padding:.8rem 1.5rem;border-radius:var(--radius);
  text-decoration:none;cursor:pointer;border:1px solid var(--ink);
  transition:opacity .18s ease,background .18s ease,color .18s ease;
}
.btn{background:var(--ink);color:var(--paper)}
.btn:hover{opacity:.85}
.btn-ghost{background:transparent;color:var(--ink);border-color:var(--line)}
.btn-ghost:hover{background:var(--paper-2)}
.btn:disabled{opacity:.45;cursor:not-allowed}

.placeholder{
  border:1px dashed var(--line);border-radius:var(--radius);
  background:var(--white);padding:3rem 1.5rem;text-align:center;
  color:var(--ink-faint);
}
.placeholder strong{display:block;color:var(--ink-soft);font-weight:500;margin-bottom:.4rem}

/* Program / book pages shown as images on a phone, where a PDF frame will
   not render. Each page reads like a sheet of paper. */
.doc-pages{display:flex;flex-direction:column;gap:.9rem}
.doc-pages img{
  width:100%;height:auto;border:1px solid var(--line);
  border-radius:var(--radius);background:var(--white);
  box-shadow:0 1px 2px rgba(37,33,28,.08),0 8px 20px -12px rgba(37,33,28,.3);
}

/* ---------- gallery: justified mosaic ----------
   Photos keep their true shape. Rows fill the width exactly, so the wall reads
   as a spread of real prints laid out on paper rather than a cropped grid. */
.gallery{width:100%}
.g-row{display:flex;flex-wrap:nowrap;width:100%}
.g-cell{
  margin:0;position:relative;cursor:zoom-in;overflow:hidden;
  border-radius:2px;background:var(--paper-2);
  box-shadow:0 1px 2px rgba(37,33,28,.10), 0 6px 16px -10px rgba(37,33,28,.35);
  transition:transform .22s cubic-bezier(.2,.7,.3,1),
             box-shadow .22s ease, opacity .5s ease;
  opacity:0;
}
.g-cell.is-loaded{opacity:1}
.g-cell img{
  width:100%;height:100%;object-fit:cover;display:block;
}
.g-cell:hover{
  transform:translateY(-3px) scale(1.012);
  box-shadow:0 2px 4px rgba(37,33,28,.14), 0 16px 30px -12px rgba(37,33,28,.5);
  z-index:2;
}
/* A soft warm wash lifts on hover — the photo "brightens" as you reach for it */
.g-cell::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg,rgba(37,33,28,.05),rgba(37,33,28,.16));
  opacity:1;transition:opacity .22s ease;
}
.g-cell:hover::after{opacity:0}
.g-cell figcaption{
  position:absolute;left:0;right:0;bottom:0;
  padding:1.4rem .7rem .55rem;
  font-family:var(--serif);font-style:italic;font-size:.9rem;color:#fff;
  background:linear-gradient(180deg,transparent,rgba(20,17,14,.78));
  opacity:0;transition:opacity .22s ease;
}
.g-cell:hover figcaption{opacity:1}

.gallery-count{
  font-size:.72rem;letter-spacing:.18em;
  text-transform:uppercase;color:var(--ink-faint);
}

/* ---------- view switch ---------- */
.view-switch{
  display:flex;align-items:center;gap:.4rem;flex-wrap:wrap;
  justify-content:center;margin:0 0 1.25rem;
}
.vs{
  font-family:var(--sans);font-size:.72rem;font-weight:500;letter-spacing:.12em;
  text-transform:uppercase;padding:.55rem 1rem;border-radius:999px;cursor:pointer;
  border:1px solid var(--line);background:var(--white);color:var(--ink-faint);
  transition:background .18s ease,color .18s ease,border-color .18s ease;
}
.vs:hover{color:var(--ink)}
.vs.is-on{background:var(--ink);color:var(--paper);border-color:var(--ink)}
.view-switch .gallery-count{margin-left:.6rem}

/* ---------- memory web ----------
   His photograph stands at the center; every memory hangs off a thread from
   him. The stage is a large virtual canvas the visitor pans and zooms. */
.web-wrap{
  position:relative;width:100%;
  height:min(78vh,760px);
  border:1px solid var(--line);border-radius:var(--radius);
  /* A warm dusk, lit from where he stands. The photographs read as lights in
     the dark, which a pale background cannot do. */
  background:
    radial-gradient(ellipse at 50% 46%,
      #3a3128 0%, #2a231c 32%, #1d1813 62%, #141110 100%);
  overflow:hidden;cursor:grab;touch-action:none;
  overscroll-behavior:contain;
  -webkit-user-select:none;user-select:none;
}
/* Vignette draws the eye inward, toward him. */
.web-wrap::after{
  content:"";position:absolute;inset:0;pointer-events:none;z-index:3;
  background:radial-gradient(ellipse at 50% 46%,
    transparent 40%, rgba(10,8,7,.35) 78%, rgba(10,8,7,.72) 100%);
}

/* Immersive mode: the web fills the screen and the page falls away.
   The exact pixel size is set from JS on the element itself, because vh, dvh
   and inset all disagree about "the screen" once a mobile URL bar is in play.
   These values are the fallback if scripting is slow to run. */
.web-wrap.is-immersive{
  position:fixed;top:0;left:0;
  width:100vw;height:100vh;
  z-index:90;border-radius:0;border:0;
}
body.web-immersive{overflow:hidden}
@media (max-width:640px){
  /* Taller on a phone so there is room to explore, and the page still has
     header, tabs and the switch above it to scroll from. */
  .web-wrap{height:min(72vh,600px)}
  .web-hint{font-size:.6rem;padding:.35rem .7rem;bottom:.5rem}
  .web-reset{font-size:.6rem;padding:.4rem .65rem}
  .web-controls{right:.5rem;top:.5rem;gap:.3rem}
  .web-node{border-width:2px}
}
.web-wrap.is-dragging{cursor:grabbing}
.web-wrap[hidden]{display:none}
.web-stage{
  position:absolute;left:0;top:0;width:3200px;height:3200px;
  transform-origin:0 0;will-change:transform;
}
.web-threads{position:absolute;left:0;top:0;width:3200px;height:3200px;
  pointer-events:none;overflow:visible}
.web-threads line{
  stroke:var(--gold-soft);stroke-width:1;opacity:.22;
  transition:opacity .25s ease,stroke-width .25s ease;
}
.web-threads line.is-lit{opacity:.9;stroke-width:1.8;stroke:#e8cf9a}
.web-threads circle{fill:none;stroke:var(--gold-soft);opacity:.07;stroke-width:1}

.web-nodes{position:absolute;left:0;top:0;width:100%;height:100%}
.web-node{
  position:absolute;border-radius:50%;overflow:hidden;cursor:pointer;
  border:2px solid rgba(255,253,250,.92);
  box-shadow:0 2px 6px rgba(0,0,0,.45), 0 0 22px -6px rgba(201,174,118,.35);
  /* `translate` is animated separately from `transform`, so the gentle drift
     never fights the hover scale. */
  transform:scale(.5);opacity:0;
  transition:transform .7s cubic-bezier(.2,.8,.3,1),
             opacity .7s ease, box-shadow .25s ease, border-color .25s ease;
  background:#2a231c;
  animation:memoryDrift 9s ease-in-out infinite;
}
.web-node.is-loaded{opacity:1;transform:scale(1)}
.web-node img{width:100%;height:100%;object-fit:cover;display:block}
.web-node:hover,.web-node.is-lit{
  transform:scale(1.22);z-index:5;
  box-shadow:0 4px 12px rgba(0,0,0,.5), 0 0 40px -4px rgba(232,207,154,.85);
  border-color:#f0dcae;
}

@keyframes memoryDrift{
  0%,100%{translate:0 0}
  50%    {translate:0 -7px}
}

.web-center{
  position:absolute;pointer-events:none;
  filter:drop-shadow(0 22px 34px rgba(0,0,0,.55));
}
.web-center img{width:100%;height:auto;display:block}
/* The light he stands in. */
.web-center::before{
  content:"";position:absolute;left:50%;top:52%;
  width:210%;height:150%;transform:translate(-50%,-50%);
  background:radial-gradient(ellipse,
    rgba(232,207,154,.30) 0%, rgba(201,174,118,.13) 38%, transparent 68%);
  pointer-events:none;z-index:-1;
  animation:centerGlow 7s ease-in-out infinite;
}
@keyframes centerGlow{
  0%,100%{opacity:.85}
  50%    {opacity:1}
}

.web-hint{
  position:absolute;left:50%;bottom:.7rem;transform:translateX(-50%);
  margin:0;font-size:.68rem;letter-spacing:.12em;text-transform:uppercase;
  color:#cfc3ae;background:rgba(20,17,16,.6);z-index:4;
  border:1px solid rgba(201,174,118,.28);
  padding:.4rem .9rem;border-radius:999px;pointer-events:none;
  transition:opacity .5s ease;backdrop-filter:blur(4px);
}
.web-hint.is-gone{opacity:0}
.web-controls{
  position:absolute;right:.7rem;top:.7rem;display:flex;gap:.35rem;z-index:5;
}
.web-reset{
  font-family:var(--sans);font-size:.65rem;letter-spacing:.1em;text-transform:uppercase;
  padding:.45rem .8rem;border-radius:999px;cursor:pointer;
  border:1px solid rgba(201,174,118,.35);
  background:rgba(20,17,16,.55);color:#d9cdb8;backdrop-filter:blur(4px);
  transition:color .2s ease,border-color .2s ease,background .2s ease;
}
.web-reset:hover{color:#fff;border-color:var(--gold-soft);background:rgba(20,17,16,.8)}

@media (prefers-reduced-motion:reduce){
  .web-node{opacity:1;transition:none}
  .web-node:hover{transform:none}
}

@media (prefers-reduced-motion:reduce){
  .g-cell{opacity:1}
  .g-cell:hover{transform:none}
}

/* ---------- lightbox ---------- */
.lightbox{
  position:fixed;inset:0;z-index:60;background:rgba(25,22,18,.94);
  display:flex;align-items:center;justify-content:center;padding:1.5rem;
}
.lightbox[hidden]{display:none}
.lb-figure{margin:0;max-width:min(1100px,92vw);text-align:center}
.lb-figure img{max-height:82vh;width:auto;margin:0 auto;border-radius:var(--radius)}
.lb-figure figcaption{
  color:#ded6c8;font-family:var(--serif);font-style:italic;
  margin-top:1rem;font-size:1rem;
}
.lb-count{
  color:#9a9084;font-size:.7rem;letter-spacing:.18em;
  margin:.6rem 0 0;font-variant-numeric:tabular-nums;
}
.lb-close,.lb-nav{
  position:absolute;background:transparent;border:0;color:#ded6c8;
  cursor:pointer;line-height:1;padding:.5rem .9rem;
}
.lb-close{top:.75rem;right:1rem;font-size:2.4rem}
.lb-nav{top:50%;transform:translateY(-50%);font-size:3rem}
.lb-prev{left:.25rem}
.lb-next{right:.25rem}
.lb-close:hover,.lb-nav:hover{color:#fff}

/* ---------- guestbook ---------- */
.gb-form{
  background:var(--white);border:1px solid var(--line);
  border-radius:var(--radius);padding:clamp(1.25rem,4vw,2rem);
  max-width:38rem;margin:0 auto 3rem;
}
.field{margin-bottom:1.25rem}
.field label{
  display:block;font-size:.68rem;letter-spacing:.16em;text-transform:uppercase;
  color:var(--gold);margin-bottom:.5rem;
}
.field input,.field textarea{
  width:100%;font-family:var(--sans);font-size:1rem;color:var(--ink);
  background:var(--paper);border:1px solid var(--line);
  border-radius:var(--radius);padding:.8rem .9rem;resize:vertical;
}
.field input:focus,.field textarea:focus{
  outline:none;border-color:var(--gold-soft);background:var(--white);
}
.counter{font-size:.72rem;color:var(--ink-faint);text-align:right;margin:.35rem 0 0}
.trap{position:absolute;left:-9999px;opacity:0;height:0;width:0}
.gb-form .btn{width:100%;border:1px solid var(--ink)}
.gb-status{
  margin:.9rem 0 0;font-size:.9rem;text-align:center;min-height:1.3em;
  color:var(--ink-soft);
}
.gb-status.is-error{color:#8c2f2f}
.gb-status.is-ok{color:#3f6b45}

.gb-wall{display:grid;gap:1rem;max-width:44rem;margin:0 auto}
.gb-empty{text-align:center;color:var(--ink-faint);font-style:italic;
  font-family:var(--serif);font-size:1.05rem}
.gb-note{
  text-align:center;color:var(--ink-faint);font-size:.85rem;
  max-width:38rem;margin:0 auto 2rem;
}
.gb-card{
  background:var(--white);border:1px solid var(--line);
  border-left:2px solid var(--gold-soft);
  border-radius:var(--radius);padding:1.2rem 1.35rem;
}
.gb-card p{
  margin:0 0 .8rem;font-family:var(--serif);font-size:1.12rem;
  line-height:1.6;color:var(--ink);white-space:pre-wrap;
}
.gb-meta{
  font-size:.7rem;letter-spacing:.13em;text-transform:uppercase;
  color:var(--ink-faint);
}
.gb-meta b{color:var(--ink-soft);font-weight:500}

/* ---------- tributes ---------- */
.tr-toggle{
  max-width:38rem;margin:0 auto 3rem;
  border:1px solid var(--line);border-radius:var(--radius);
  background:var(--white);
}
.tr-toggle summary{
  cursor:pointer;list-style:none;padding:1rem 1.25rem;
  font-size:.75rem;font-weight:500;letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink);text-align:center;
}
.tr-toggle summary::-webkit-details-marker{display:none}
.tr-toggle summary:hover{color:var(--gold)}
.tr-toggle[open] summary{border-bottom:1px solid var(--line)}
.tr-toggle .gb-form{border:0;margin:0;max-width:none}
.field .opt{
  text-transform:none;letter-spacing:0;color:var(--ink-faint);
  font-size:.9em;
}

.tribute{
  background:var(--white);border:1px solid var(--line);
  border-left:2px solid var(--gold-soft);
  border-radius:var(--radius);padding:1.5rem 1.6rem;
}
.tribute .body{
  font-family:var(--serif);font-size:1.15rem;line-height:1.7;
  color:var(--ink);white-space:pre-wrap;margin:0 0 1.1rem;
}
.tribute .by{
  font-size:.7rem;letter-spacing:.13em;text-transform:uppercase;
  color:var(--ink-faint);
}
.tribute .by b{color:var(--ink-soft);font-weight:500}
.tribute .rel{font-style:italic;text-transform:none;letter-spacing:.02em}

/* ---------- photo picker + attached photos ---------- */
.ph-input{
  display:block;width:100%;font-family:var(--sans);font-size:.85rem;
  color:var(--ink-soft);padding:.6rem 0;
}
.ph-input:disabled{opacity:.45}
.ph-strip{display:flex;gap:.5rem;flex-wrap:wrap}
.ph-strip:not(:empty){margin-bottom:.7rem}
.ph-thumb{position:relative;width:84px;height:84px}
.ph-thumb img{
  width:100%;height:100%;object-fit:cover;
  border-radius:var(--radius);border:1px solid var(--line);
}
.ph-remove{
  position:absolute;top:-7px;right:-7px;width:22px;height:22px;
  border-radius:50%;border:1px solid var(--line);background:var(--white);
  color:var(--ink);font-size:15px;line-height:1;cursor:pointer;padding:0;
  box-shadow:0 1px 3px rgba(37,33,28,.2);
}
.ph-remove:hover{background:#f7eaea;color:#8c2f2f}

.att{display:flex;gap:.5rem;flex-wrap:wrap;margin:0 0 .9rem}
.att img{
  width:120px;height:120px;object-fit:cover;cursor:zoom-in;
  border-radius:var(--radius);border:1px solid var(--line);
  transition:opacity .18s ease;
}
.att img:hover{opacity:.85}

/* ---------- footer ---------- */
.foot{
  text-align:center;padding:3rem 1.25rem 4rem;
  border-top:1px solid var(--line);background:var(--paper-2);
}
.foot p{margin:0}
#footName{font-family:var(--serif);font-size:1.35rem;color:var(--ink)}
.small{font-size:.85rem;color:var(--ink-faint);margin-top:.5rem !important}

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