/* =====================================================================
   THE GARDEN ROOM: redesign pass 1, the "Who we are" section.

   A downtown Charleston house with an Art Deco Revival hand: aged
   limewash plaster, a stepped arch with a sunburst in its head, hand-
   coloured engravings in the logo's own palette, and a brick terrace
   that lays itself as you scroll. Motion is slow and small; everything
   stops for anyone who asked for less.
   ===================================================================== */
:root{
  --ink-forest:#2c3a2b;      /* the monogram's green */
  --sage:#7d8b6a;
  --tan:#a38a66;             /* "Landscape Co." in the logo */
  --tan-soft:#c4ae8b;
  --plaster:#f1ebe0;
}

/* ---------- plaster ------------------------------------------------- */
.parlor{
  position:relative;overflow:hidden;isolation:isolate;
  background:var(--surface);
  padding:clamp(96px,11vw,168px) 0 0;
}
/* two layers of noise: a fine grain, and slow blotches like limewash
   that has dried unevenly. Both fade out at the top and bottom so the
   section meets its neighbours on the plain oyster ground. */
.parlor::before,.plaster::before{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='260' height='260'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .35 0 0 0 0 .29 0 0 0 0 .2 0 0 0 .55 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1600' height='1600' viewBox='0 0 1600 1600' preserveAspectRatio='none'%3E%3Cfilter id='m'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.0032' numOctaves='4' seed='7'/%3E%3CfeColorMatrix values='0 0 0 0 .62 0 0 0 0 .52 0 0 0 0 .36 1.3 0 0 0 -.5'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23m)'/%3E%3C/svg%3E");
  background-size:260px 260px,100% 100%;background-repeat:repeat,no-repeat;
  opacity:.5;
  -webkit-mask-image:linear-gradient(transparent,#000 14%,#000 80%,transparent);
          mask-image:linear-gradient(transparent,#000 14%,#000 80%,transparent);
}

/* ---------- layout -------------------------------------------------- */
.parlor-in{
  display:grid;grid-template-columns:minmax(0,1.08fr) minmax(0,.92fr);
  grid-template-areas:"head niche" "body niche" "body legend";
  column-gap:clamp(48px,8vw,140px);align-items:start;
  position:relative;z-index:2;
}
.parlor-head{grid-area:head}
.parlor-body{grid-area:body;align-self:start}
.niche{grid-area:niche;margin:0;position:relative;justify-self:center;
  width:min(100%,440px);padding-top:40px}

.parlor .eyebrow{display:inline-flex;align-items:center;gap:12px;color:var(--tan-text)}
.parlor .fan{width:24px;height:13px;fill:none;stroke:currentColor;stroke-width:1.1}

/* the heading rises word by word out of its own line */
.parlor-h{
  font-family:var(--display);font-weight:600;
  font-size:clamp(44px,5.8vw,92px);line-height:1.02;letter-spacing:-.025em;
  color:var(--ink-forest);margin:22px 0 clamp(36px,4vw,56px);max-width:9ch;
}
.parlor-h.rv{opacity:1;transform:none}
.parlor-h .w{display:inline-block;overflow:hidden;vertical-align:top;padding-bottom:.08em;margin-bottom:-.08em}
.parlor-h .w>span{display:inline-block;transform:translateY(108%);
  transition:transform 1.1s cubic-bezier(.19,1,.22,1);transition-delay:calc(var(--i) * 90ms)}
.parlor-h.in .w>span{transform:none}

/* the facts, set as the legend of an old plate */
.legend{grid-area:legend;margin:44px 0 0;display:grid;gap:0;border-top:1px solid var(--outline-variant);
  width:min(100%,460px);justify-self:center}
.legend>div{display:grid;grid-template-columns:136px 1fr;gap:20px;padding:18px 0;
  border-bottom:1px solid var(--outline-variant)}
.legend dt{font-family:var(--body);font-size:11px;font-weight:600;letter-spacing:.16em;
  text-transform:uppercase;color:var(--outline);display:flex;align-items:baseline;gap:12px;margin:0}
.legend dt b{font-family:var(--display);font-weight:600;font-size:15px;letter-spacing:.04em;
  color:var(--tan-text);min-width:24px}
.legend dd{margin:0;font-size:16px;line-height:1.5;color:var(--on-surface)}

/* ---------- the arch -------------------------------------------------- */
.niche-arch{position:relative;z-index:2;--open:0}
.niche-win{
  position:relative;aspect-ratio:2/3;overflow:hidden;background:var(--surface-container);
  clip-path:inset(calc((1 - var(--open)) * 14%) calc((1 - var(--open)) * 26%) 0 round 999px 999px 0 0);
}
.niche-img{width:100%;height:100%;object-fit:cover;
  transform:scale(calc(1 + (1 - var(--open)) * .22)) translateY(var(--drift,0px));
  transform-origin:50% 70%;will-change:transform}
.niche-frame{position:absolute;inset:0;width:100%;height:100%;overflow:visible;pointer-events:none}
.niche-frame path{fill:none;vector-effect:non-scaling-stroke;
  stroke-dasharray:1;stroke-dashoffset:calc(1 - var(--open))}
.niche-frame .fr-band{fill:#f6f1e7;stroke:none;stroke-dasharray:none;opacity:var(--open)}
.niche-frame .fr-in{stroke:var(--ink-forest);stroke-opacity:.45;stroke-width:1}
.niche-frame .fr-tan{stroke:var(--tan);stroke-width:1.2}
.niche-frame .fr-out{stroke:var(--ink-forest);stroke-opacity:.7;stroke-width:1.3}
.niche-frame .fr-ray,.niche-frame .fr-flute{stroke:var(--tan);stroke-opacity:.75;stroke-width:1}
.niche-frame .fr-base{stroke:var(--ink-forest);stroke-opacity:.55;stroke-width:1.2}
.niche-frame .fr-rose{fill:var(--tan);opacity:var(--open)}
.niche-frame .fr-key{opacity:var(--open)}
.niche-frame .fr-keyblock{fill:var(--plaster);stroke:var(--tan);stroke-width:1.2;vector-effect:non-scaling-stroke;
  stroke-dasharray:none;stroke-dashoffset:0}
.niche-frame .moon{fill:var(--tan);stroke:none;stroke-dasharray:none;
  transition:fill 1.2s ease,filter 1.2s ease}

.plate-cap{margin:52px 0 0;display:flex;flex-wrap:wrap;justify-content:center;align-items:baseline;
  gap:6px 16px;text-align:center;color:var(--outline)}
.plate-cap .pl-no{font-family:var(--display);font-weight:600;font-size:15px;color:var(--tan-text)}
.plate-cap .pl-t{font-family:var(--body);font-size:11px;font-weight:600;letter-spacing:.18em;text-transform:uppercase}
.plate-cap .pl-t::before,.plate-cap .pl-t::after{content:"\00b7";margin:0 12px;color:var(--tan-text)}

/* Easter egg: the state motto translates itself when you look at it */
.motto{position:relative;display:inline-grid;font-family:var(--display);font-weight:600;
  font-size:14px;letter-spacing:.06em;color:var(--ink-forest);cursor:help;outline:none}
.motto>span,.motto::after{grid-area:1/1;transition:opacity .5s ease,transform .5s ease}
.motto::after{content:attr(data-en);opacity:0;transform:translateY(6px);white-space:nowrap;justify-self:center}
.motto:hover>span,.motto:focus>span{opacity:0;transform:translateY(-6px)}
.motto:hover::after,.motto:focus::after{opacity:1;transform:none}

/* ---------- painted plants ------------------------------------------- */
.pl-art{position:absolute;pointer-events:none;will-change:transform}
.pl-art img{width:100%;height:auto;display:block}
.pl-oak{top:-7%;right:-16vw;width:min(54vw,940px);z-index:1;
  -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 22%);
          mask-image:linear-gradient(90deg,transparent 0,#000 22%)}
.pl-oak{pointer-events:auto}
.pl-frond{left:-42%;top:2%;width:78%;z-index:1;transform-origin:50% 100%}
.pl-frond img{rotate:-14deg}
.pl-magnolia{right:-46%;top:40%;width:66%;z-index:4;pointer-events:auto}
.magnolia-btn{all:unset;display:block;cursor:pointer;width:100%}
.magnolia-btn:focus-visible{outline:1px solid var(--tan);outline-offset:6px}

/* the plants breathe: a slow sway, each on its own period so they never
   fall into step */
@keyframes sway{0%,100%{transform:rotate(-1deg)}50%{transform:rotate(1.1deg)}}
@keyframes sway-oak{0%,100%{transform:skewX(-.6deg) rotate(.2deg)}50%{transform:skewX(.8deg) rotate(-.2deg)}}
@keyframes gust{0%{transform:skewX(0)}20%{transform:skewX(4deg) rotate(-.6deg)}45%{transform:skewX(-2.5deg)}70%{transform:skewX(1.4deg)}100%{transform:skewX(0)}}
.pl-oak .sway{transform-origin:50% 12%;animation:sway-oak 9s ease-in-out infinite}
.pl-oak.gust .sway{animation:gust 2.4s cubic-bezier(.3,.6,.3,1) 1}
.pl-frond .sway{transform-origin:40% 100%;animation:sway 7.5s ease-in-out infinite}
.pl-magnolia .sway{transform-origin:78% 96%;animation:sway 11s ease-in-out -3s infinite}

/* Easter egg: a magnolia petal falls when you tap the bloom */
.petal{position:absolute;z-index:6;width:26px;height:34px;pointer-events:none;
  background:radial-gradient(120% 90% at 30% 20%,#fffdf6 0,#f2e9d6 55%,#dccdae 100%);
  border-radius:50% 50% 46% 54% / 62% 62% 38% 38%;
  box-shadow:inset -2px -3px 5px rgba(120,95,60,.18);
  animation:petal var(--dur,5.5s) cubic-bezier(.45,.05,.55,.95) forwards}
@keyframes petal{
  0%{transform:translate(0,0) rotate(0);opacity:0}
  8%{opacity:1}
  30%{transform:translate(calc(var(--dx) * .4),calc(var(--dy) * .28)) rotate(140deg)}
  60%{transform:translate(calc(var(--dx) * -.2),calc(var(--dy) * .62)) rotate(260deg)}
  88%{opacity:1}
  100%{transform:translate(calc(var(--dx) * .3),var(--dy)) rotate(380deg);opacity:0}
}

/* ---------- the seal ---------------------------------------------------- */
.seal{all:unset;position:absolute;z-index:5;left:-58px;top:calc(40px + 72%);width:132px;height:132px;cursor:pointer;
  transform:rotate(var(--turn,0deg));transition:transform .2s linear}
.seal svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible}
.seal circle{fill:var(--plaster);stroke:var(--tan);stroke-width:1}
.seal circle+circle{fill:none;stroke-opacity:.6}
.seal text{font-family:var(--body);font-size:12.5px;font-weight:600;letter-spacing:.22em;text-transform:uppercase;fill:var(--ink-forest)}
.seal img{position:absolute;left:50%;top:50%;width:52%;height:auto;transform:translate(-50%,-50%) rotate(calc(var(--turn,0deg) * -1))}
.seal:focus-visible{outline:1px solid var(--tan);outline-offset:6px}
.seal.spin{transition:transform 1.6s cubic-bezier(.2,.8,.2,1)}

/* ---------- the wren ---------------------------------------------------- */
/* waits off the page; lands on the keystone once you have lingered */
.wren{all:unset;position:absolute;z-index:6;left:calc(50% - 50px);top:calc(-7.6% - 64px);width:86px;cursor:pointer;
  opacity:0;pointer-events:none;
  transform:translate(70vw,-40vh) rotate(-18deg) scale(.8);
  transition:transform 2.2s cubic-bezier(.3,.7,.25,1),opacity .6s ease}
.wren img{width:100%;height:auto;display:block}
.wren.landed{opacity:1;pointer-events:auto;transform:none}
.wren.landed img{animation:hop 5s ease-in-out 2.4s infinite}
@keyframes hop{0%,82%,100%{transform:none}86%{transform:translateY(-7px) rotate(-4deg)}90%{transform:none}94%{transform:translateY(-4px)}}
.wren.gone{opacity:0;pointer-events:none;transform:translate(-60vw,-55vh) rotate(-24deg) scale(.7);
  transition:transform 1.6s cubic-bezier(.5,0,.75,.4),opacity 1.2s ease .4s}
.wren-song{position:absolute;right:92%;top:-22px;white-space:nowrap;
  font-family:var(--display);font-weight:600;font-size:15px;color:var(--ink-forest);
  opacity:0;transform:translateY(6px);transition:opacity .4s ease,transform .4s ease}
.wren.sing .wren-song{opacity:1;transform:none}
.wren:focus-visible{outline:1px solid var(--tan);outline-offset:4px}

/* ---------- night: the crescent from the state flag lights up ------------ */
.parlor.is-night .moon{fill:#f3d98b;filter:drop-shadow(0 0 5px rgba(243,217,139,.9))}
/* evening falls over the photograph and the porch lantern comes on */
.niche-win::after{content:"";position:absolute;inset:0;pointer-events:none;opacity:0;
  background:linear-gradient(180deg,rgba(22,30,58,.85) 0%,rgba(30,38,66,.7) 45%,rgba(34,40,60,.6) 100%);
  mix-blend-mode:multiply;transition:opacity 1.5s ease}
.parlor.is-night .niche-win::after{opacity:.75}
/* the copper gas lanterns on the piazza */
.lamp{position:absolute;left:var(--x);top:var(--y);width:16%;aspect-ratio:1;z-index:1;pointer-events:none;
  transform:translate(-50%,-50%);border-radius:50%;opacity:0;mix-blend-mode:screen;
  background:radial-gradient(closest-side,rgba(255,214,140,.95),rgba(255,190,110,.35) 35%,rgba(255,180,100,0) 100%);
  transition:opacity 1.2s ease 1.2s}
.lamp.sm{width:11%}
.parlor.is-night .lamp{opacity:1;animation:flicker 5s ease-in-out 2.4s infinite}
.parlor.is-night .lamp:nth-of-type(2){animation-delay:3.1s}
.parlor.is-night .lamp:nth-of-type(3){animation-delay:2.7s}
@keyframes flicker{0%,100%{opacity:1}47%{opacity:.9}50%{opacity:.97}53%{opacity:.88}}

/* ---------- the terrace ------------------------------------------------- */
.terrace{position:relative;height:210px;margin-top:clamp(20px,3vw,48px);z-index:3;perspective:760px;perspective-origin:50% -40%}
.terrace-floor{position:absolute;left:-15%;right:-15%;bottom:0;height:400px;
  transform:rotateX(58deg);transform-origin:50% 100%}
/* its soft edges are painted into the canvas by parlor.js, not masked here */
.terrace-svg{position:absolute;inset:0;width:100%;height:100%;display:block}
/* each brick is set as the scroll reaches it (parlor.js switches .on brick by brick;
   the old way recalculated every brick on every frame, which stuttered on phones) */
.terrace .hatch{opacity:0;transition:opacity .6s ease}
.terrace .hatch.on{opacity:.9}
.terrace .pv{transform-box:fill-box;transform-origin:center;opacity:0;transform:scale(.55);
  transition:opacity .35s ease,transform .45s cubic-bezier(.2,.7,.2,1)}
.terrace .pv.on{opacity:1;transform:none}
.terrace .joint{fill:none;stroke:#7f6d58;stroke-opacity:.55;stroke-width:1}

/* Easter egg: an anole on the edge of the terrace, doing push-ups */
.pl-urn{position:absolute;left:max(24px,7vw);bottom:34%;width:clamp(120px,14vw,210px);z-index:5;pointer-events:none}
.pl-urn img{width:100%;height:auto;display:block;filter:drop-shadow(0 18px 14px rgba(70,55,35,.18))}
.anole{position:absolute;left:calc(max(24px,7vw) + 20px);bottom:calc(34% + 2px);width:130px;height:auto;z-index:4;cursor:pointer;
  transform:translateX(0);transition:transform 1.2s cubic-bezier(.3,.7,.3,1)}
.anole.peek{transform:translateX(clamp(70px,9vw,120px))}
.anole.peek.pushups{animation:pushups 1.6s ease-in-out 2}
@keyframes pushups{0%,100%{translate:0 0}20%{translate:0 -6px}40%{translate:0 0}60%{translate:0 -6px}80%{translate:0 0}}
.anole.run{transform:translateX(calc(100vw + 40px));transition:transform 1.5s cubic-bezier(.55,.05,.7,.4)}
.anole.reset{transition:none;transform:translateX(0)}

/* ---------- phones and tablets ----------------------------------------- */
@media(max-width:900px){
  .parlor-in{grid-template-columns:1fr;grid-template-areas:"head" "niche" "body" "legend"}
  .legend{justify-self:stretch;width:auto}
  .parlor-h{max-width:none}
  .niche{width:min(78%,420px);margin:76px auto 20px}
  .parlor-body{padding-bottom:0}
  .parlor{padding-top:170px}
  .pl-oak{width:110vw;right:-40vw;top:-150px}
  .pl-frond{left:-34%;width:66%}
  .pl-magnolia{right:-30%;width:54%}
  .seal{width:104px;height:104px;left:-38px}
  .legend>div{grid-template-columns:120px 1fr}
  .terrace{height:150px;margin-top:130px}
  .terrace-floor{height:300px}
  .anole{width:96px}
}
@media(max-width:560px){
  .parlor{padding-top:150px}
  .niche{width:74%}
  .pl-oak{width:130vw;right:-52vw;top:-190px}
  .seal{top:calc(40px + 56%);left:-30px;width:92px;height:92px}
  .plate-cap .pl-t::before,.plate-cap .pl-t::after{margin:0 8px}
  .legend>div{grid-template-columns:1fr;gap:6px}
}

/* anyone who asked for less motion gets the finished room */
@media (prefers-reduced-motion: reduce){
  .niche-arch{--open:1 !important}
  .niche-img{transform:none}
  .sway,.pl-oak .sway,.pl-frond .sway,.pl-magnolia .sway{animation:none}
  .parlor-h .w>span{transform:none;transition:none}
  .terrace .pv,.terrace .hatch{opacity:1 !important;transform:none !important;transition:none}
  .pl-art{transform:none !important}
  .wren,.anole,.seal{transition:none}
}
.wren.reset-wren{transition:none !important}
.terrace{pointer-events:auto}

/* ---------- the arch and the plants on the browser's own scroll timeline ------
   Where the browser can, the arch opens, its photograph drifts and the painted
   plants move at their own speeds as scroll-driven animations, in step with
   the page (no lag on a busy frame, no jump when a phone's toolbar moves).
   parlor.js sets --sp from each plant's data-speed and --ph/--ah (half the
   section's and the arch's height), and draws all of this by hand elsewhere.
   The distances match parlor.js exactly. */
@property --open{syntax:'<number>';inherits:true;initial-value:0}
@property --drift{syntax:'<length>';inherits:false;initial-value:0px}
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .parlor{view-timeline-name:--parlor}
    .niche-arch{view-timeline-name:--arch;animation:pl-open both cubic-bezier(.33,1,.68,1);animation-timeline:view();animation-range:cover 0% cover calc(var(--sh,100vh) * .7)}
    .niche-img{animation:pl-drift both linear;animation-timeline:--arch;animation-range:cover 0% cover 100%}
    .parlor .pl-art[data-speed]{animation:pl-art both linear;animation-timeline:--parlor;animation-range:cover 0% cover 100%}
  }
}
@keyframes pl-open{from{--open:0}to{--open:1}}
@keyframes pl-drift{from{--drift:calc((var(--sh,100vh) * .5 + var(--ah,330px)) * -.05)}to{--drift:calc((var(--sh,100vh) * .5 + var(--ah,330px)) * .05)}}
@keyframes pl-art{from{transform:translate3d(0,calc((var(--sh,100vh) * .5 + var(--ph,700px)) * var(--sp,0)),0)}
  to{transform:translate3d(0,calc((var(--sh,100vh) * .5 + var(--ph,700px)) * var(--sp,0) * -1),0)}}
