/* Layout: a print shop proof sheet on white. Dashed die-cut lines carry the
   structure; real product sheets sit as cut-out cards on soft pink stock. */
:root{
  /* Sampled from the logo: heart #E01A56, wordmark plum #34021E. */
  --paper:#FFFFFF;
  --blush:#FFEBF3;
  --wash:#FFF4F8;
  --card:#FFFFFF;
  --ink:#34021E;
  --ink-soft:#7A5566;
  --rose:#E01A56;
  --rose-soft:#F79FBC;
  --cut:#FAC8DB;
  --lift:0 10px 30px rgba(224,26,86,.12);
  color-scheme:light;

  --display:"Gloock",Georgia,"Times New Roman",serif;
  --body:"Karla","Helvetica Neue",Arial,sans-serif;
  --spec:"IBM Plex Mono",ui-monospace,"Courier New",monospace;
}
/* This brand commits to one look: white paper and soft pink. The page stays
   light even when the viewer's device is set to dark mode, so every colour is
   declared above and no dark overrides exist. */

*{box-sizing:border-box}
body{
  margin:0;
  /* pink wash down the top of the page, settling into white */
  background:var(--paper);
  background-image:linear-gradient(180deg,var(--blush) 0%,var(--wash) 34%,var(--paper) 62%);
  background-repeat:no-repeat;
  background-size:100% 62rem;
  color:var(--ink);
  font-family:var(--body);
  font-size:1rem;
  line-height:1.65;
  -webkit-font-smoothing:antialiased;
}
body::before{
  content:"";position:fixed;inset:0 0 auto;
  height:env(safe-area-inset-top,0px);z-index:12;background:var(--blush);
}
.wrap{
  max-width:64rem;margin:0 auto;
  padding-left:max(16px,env(safe-area-inset-left,0px));
  padding-right:max(16px,env(safe-area-inset-right,0px));
}
h1,h2,h3{font-family:var(--display);font-weight:400;text-wrap:balance;margin:0;line-height:1.14;letter-spacing:-.01em}
p{margin:0}
a{color:inherit}
img{display:block;max-width:100%}

nav{
  --navpad:.85rem;
  position:sticky;top:env(safe-area-inset-top,0px);z-index:11;
  /* translucent so the pink wash shows through at the top of the page */
  background:rgba(255,255,255,.78);
  -webkit-backdrop-filter:blur(12px);
  backdrop-filter:blur(12px);
  border-bottom:1px dashed var(--cut);
}
/* logo takes the left, everything else packs against the right edge, so the
   links sit beside the Shop button instead of floating in the middle */
.navin{display:flex;align-items:center;justify-content:flex-start;gap:1.4rem;padding-block:var(--navpad)}
.navin>.mark{margin-right:auto}
.mark{display:inline-flex;align-items:center;text-decoration:none;min-width:0}
.mark img{height:2.1rem;width:auto;max-width:min(62vw,15rem)}
@media (max-width:420px){.mark img{height:1.75rem}}
/* both wordmarks run well above the 2.1rem base size */
.navin .mark img{height:3.4rem}
footer .mark img{height:3.25rem}
@media (max-width:420px){.navin .mark img{height:2.7rem}}
@media (max-width:420px){footer .mark img{height:2.6rem}}
.navlinks{display:flex;align-self:stretch;align-items:center;gap:1.2rem;font-size:.8rem;letter-spacing:.04em;text-transform:uppercase;font-family:var(--spec)}
.navlinks a{text-decoration:none;color:var(--ink-soft);white-space:nowrap}
.navlinks a:hover{color:var(--rose)}
@media (max-width:900px){.navlinks{display:none}}

.spec{font-family:var(--spec);font-size:.72rem;letter-spacing:.14em;text-transform:uppercase;color:var(--rose)}

/* ---- hero ---- */
.hero{padding-block:clamp(2.5rem,7vw,4rem) clamp(2.5rem,7vw,4.5rem)}
/* the badge strip is a thin line of text, not a heading, so it does not need
   the full hero inset above it: pull it up close under the nav */
.hero:has(>.trust:first-child){padding-top:clamp(1rem,2.2vw,1.5rem)}
/* minmax(0,...) is load bearing: the stack's children are absolutely positioned,
   so it has no intrinsic width, and a bare fr track lets the headline steal the
   whole row and collapse the image column to nothing. */
.hero-grid{
  display:grid;
  grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);
  gap:clamp(2rem,5vw,3.5rem);align-items:center;
}
@media (max-width:860px){.hero-grid{grid-template-columns:minmax(0,1fr)}}
.hero h1{font-size:clamp(2.5rem,7vw,4.3rem);margin-block:1rem .9rem}
/* the top margin only exists to clear the small label above the headline,
   so drop it when the headline is the first thing in the hero */
.hero h1:first-child{margin-top:0}
.hero h1 em{font-style:italic;color:var(--rose)}
.lede{font-size:clamp(1.02rem,1.9vw,1.18rem);color:var(--ink-soft);max-width:36ch}

/* trust strip */
.trust{
  display:flex;flex-wrap:wrap;gap:.5rem 1.4rem;margin-top:1.7rem;
  padding-top:1.2rem;border-top:1px dashed var(--cut);
  font-family:var(--spec);font-size:.7rem;letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink-soft);
}
.trust span{display:inline-flex;align-items:center;gap:.45rem}
.trust span::before{content:"";width:.4rem;height:.4rem;border-radius:50%;background:var(--rose);flex:none}
/* when the strip leads the hero instead of closing it, the dashed rule belongs
   underneath it and the spacing flips with it */
.hero .trust:first-child{
  margin-top:0;margin-bottom:1.3rem;
  padding-top:0;padding-bottom:1.1rem;
  border-top:0;border-bottom:1px dashed var(--cut);
}

/* stacked product shots */
/* width:100% is required. Every child is absolutely positioned, so without an
   explicit width this box has no content to size from and collapses to zero
   (auto margins would also stop it stretching to the grid track). */
.stack{position:relative;width:100%;aspect-ratio:1/1.02}
.stack figure{
  position:absolute;margin:0;width:56%;border-radius:.9rem;overflow:hidden;
  border:1.5px dashed var(--cut);background:var(--blush);box-shadow:var(--lift);
}
.stack figure img{width:100%;height:auto;aspect-ratio:480/679;object-fit:cover}
.stack .s1{left:0;top:2%;transform:rotate(-6deg);z-index:1}
.stack .s2{right:0;top:0;transform:rotate(5deg);z-index:2}
.stack .s3{left:22%;bottom:0;transform:rotate(-1.5deg);z-index:3}
.stack-cap{
  position:absolute;left:0;right:0;bottom:-1.9rem;text-align:center;
  font-family:var(--spec);font-size:.68rem;letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink-soft);
}
@media (max-width:560px){
  .stack{aspect-ratio:auto;display:grid;grid-template-columns:repeat(3,1fr);gap:.6rem}
  .stack figure{position:static;width:auto;transform:none;box-shadow:none}
  .stack-cap{position:static;margin-top:.8rem}
}

.btn{
  display:inline-flex;align-items:center;gap:.5rem;
  font-family:var(--spec);font-size:.78rem;letter-spacing:.1em;text-transform:uppercase;
  text-decoration:none;padding:.8rem 1.3rem;border-radius:2rem;
  background:var(--rose);color:#FFFFFF;border:1.5px solid var(--rose);
  transition:transform .14s ease,opacity .14s ease;
}
.btn:hover{transform:translateY(-1px);opacity:.88}
.btn.ghost{background:transparent;color:var(--ink);border-color:var(--cut)}
.btn.ghost:hover{background:var(--blush);border-color:var(--rose);opacity:1}
.btn-row{display:flex;flex-wrap:wrap;gap:.7rem;margin-top:1.6rem}
.btn:focus-visible,button:focus-visible,a:focus-visible{outline:2px solid var(--rose);outline-offset:3px}

.band{border-top:1px dashed var(--cut);padding-block:clamp(2.75rem,7vw,4.5rem)}
/* a hero's bottom inset and the next band's top inset stacked to ~144px of
   empty page, which pushed the first thing in the band below the fold. The
   dashed rule between them already does the separating, so halve the junction. */
.hero:has(+ .band){padding-bottom:clamp(1.75rem,3.5vw,2.5rem)}
.hero + .band{padding-top:clamp(1.5rem,3vw,2.25rem)}
.band.tint{background:var(--blush)}
.band-head{max-width:46ch;margin-bottom:2.25rem}
.band-head h2{font-size:clamp(1.8rem,4.2vw,2.7rem);margin-block:.7rem .7rem}
.band-head p{color:var(--ink-soft)}

/* ---- product cards ---- */
/* category header: names the group of cards under it, with a dashed rule
   running out to the right so it reads as a divider rather than a heading */
.cat{display:flex;flex-wrap:wrap;align-items:baseline;gap:.5rem .9rem;margin-bottom:1.3rem}
.cat h3{font-size:clamp(1.15rem,2.4vw,1.45rem)}
.cat span{
  font-family:var(--spec);font-size:.68rem;letter-spacing:.12em;text-transform:uppercase;
  color:var(--ink-soft);
}
.cat::after{content:"";flex:1 1 4rem;height:1px;background:var(--cut);
  background-image:repeating-linear-gradient(90deg,var(--cut) 0 6px,transparent 6px 11px);
  background-color:transparent;align-self:center;min-width:2rem}
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(16rem,1fr));gap:1.4rem}
.item{position:relative;min-width:0;background:var(--card);border:1.5px dashed var(--cut);border-radius:1.1rem;overflow:hidden;display:flex;flex-direction:column}
.item.pick{border-style:solid;border-color:var(--rose);border-width:2px}
.shotwrap{background:var(--blush);border-bottom:1px dashed var(--cut)}
.shotwrap img{width:100%;height:auto;aspect-ratio:480/679;object-fit:cover;max-width:100%}
.item-body{padding:1.15rem 1.25rem 1.35rem;display:flex;flex-direction:column;gap:.45rem;flex:1}
.item h4{font-family:var(--display);font-weight:400;font-size:1.2rem;margin:0;line-height:1.2}
.item p{font-size:.88rem;color:var(--ink-soft);flex:1}
.item .price{font-family:var(--spec);font-size:1rem;font-weight:500;color:var(--rose);font-variant-numeric:tabular-nums}
.item .tags{font-family:var(--spec);font-size:.67rem;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-soft)}
.flag{position:absolute;top:.9rem;right:.9rem;z-index:2;background:var(--rose);color:#FFFFFF;font-family:var(--spec);font-size:.62rem;letter-spacing:.12em;text-transform:uppercase;padding:.25rem .65rem;border-radius:1rem}


/* ---- spec sheet ---- */
.specsheet{border:1.5px dashed var(--cut);border-radius:1rem;background:var(--card);padding:1.5rem;font-family:var(--spec);font-size:.86rem}
.specsheet dl{display:grid;grid-template-columns:auto 1fr;gap:.55rem 1.4rem;margin:0}
.specsheet dt{color:var(--rose);letter-spacing:.08em;text-transform:uppercase;font-size:.7rem;align-self:center}
.specsheet dd{margin:0;font-variant-numeric:tabular-nums;color:var(--ink-soft)}
@media (max-width:460px){.specsheet dl{grid-template-columns:1fr}.specsheet dd{margin-bottom:.5rem}}

/* ---- about ---- */
.about{display:grid;grid-template-columns:.7fr 1.3fr;gap:clamp(1.75rem,5vw,3.5rem);align-items:center}
@media (max-width:760px){.about{grid-template-columns:1fr}}
.portrait{border-radius:1.1rem;overflow:hidden;border:1.5px dashed var(--cut);background:var(--blush);max-width:14rem}
.portrait img{width:100%;height:auto;aspect-ratio:1;object-fit:cover}
.about p{color:var(--ink-soft);margin-bottom:1rem;max-width:56ch}
.about h2{font-size:clamp(1.7rem,4vw,2.4rem);margin-block:.6rem 1rem}
.quote{font-family:var(--display);font-size:1.18rem;line-height:1.45;color:var(--ink);border-left:2px solid var(--rose);padding-left:1.1rem;margin-bottom:0}

/* ---- contact ---- */
.contact{text-align:center;max-width:40rem;margin-inline:auto}
.contact h2{font-size:clamp(2rem,5vw,3rem);margin-block:.8rem 1rem}
.contact>p{color:var(--ink-soft)}
.contact .btn-row{justify-content:center;margin-top:2rem}
.contact-fields{display:flex;flex-direction:column;align-items:center;gap:.7rem;margin-top:1.8rem}
.field{display:flex;flex-wrap:wrap;gap:.6rem;align-items:center;justify-content:center}
.field-label{
  font-family:var(--spec);font-size:.67rem;letter-spacing:.12em;text-transform:uppercase;
  color:var(--rose);min-width:4rem;text-align:right;
}
@media (max-width:440px){.field-label{min-width:0;text-align:center;width:100%}}
.field-note{font-family:var(--spec);font-size:.72rem;color:var(--ink-soft);margin-top:.4rem}
.mailbox{font-family:var(--spec);font-size:.9rem;background:var(--card);border:1.5px dashed var(--cut);border-radius:.6rem;padding:.65rem .9rem;user-select:all;word-break:break-all;min-width:0}

footer{border-top:1px dashed var(--cut);padding-block:2.5rem 3rem;background:var(--blush)}
.foot{display:flex;flex-wrap:wrap;gap:1.5rem;justify-content:space-between;align-items:flex-start}
.foot-links{display:flex;flex-wrap:wrap;gap:1.2rem;font-family:var(--spec);font-size:.8rem}
.foot-links a{text-decoration:none;color:var(--ink-soft)}
.foot-links a:hover{color:var(--rose)}
.foot small{color:var(--ink-soft);font-family:var(--spec);font-size:.72rem;letter-spacing:.06em}

/* ===== motion =====================================================
   Two kinds only. A short load sequence in the hero, and hover feedback
   on things you can click. Blocks further down reveal on scroll through
   a view() timeline, which simply does nothing in browsers that lack it,
   so no content ever depends on script to become visible. ============ */

@keyframes rise{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
@keyframes fan-l{from{opacity:0;transform:translate(26px,18px) rotate(0deg)}to{opacity:1;transform:rotate(-6deg)}}
@keyframes fan-r{from{opacity:0;transform:translate(-26px,18px) rotate(0deg)}to{opacity:1;transform:rotate(5deg)}}
@keyframes fan-c{from{opacity:0;transform:translateY(26px) rotate(0deg)}to{opacity:1;transform:rotate(-1.5deg)}}

@media (prefers-reduced-motion: no-preference){
  /* hero load sequence: fill is backwards, so once it finishes the element
     falls back to its own CSS and hover transforms still work. */
  .hero .spec,
  .hero h1,
  .hero .lede,
  .hero .btn-row,
  .hero .trust{animation:rise .55s cubic-bezier(.22,.7,.3,1) backwards}
  .hero .spec{animation-delay:.04s}
  .hero h1{animation-delay:.11s}
  .hero .lede{animation-delay:.19s}
  .hero .btn-row{animation-delay:.26s}
  .hero .trust{animation-delay:.33s}
  .hero .trust:first-child{animation-delay:.04s}
  .stack-cap{animation:rise .5s ease .5s backwards}

  @media (min-width:561px){
    .stack .s1{animation:fan-l .7s cubic-bezier(.22,.7,.3,1) .16s backwards}
    .stack .s2{animation:fan-r .7s cubic-bezier(.22,.7,.3,1) .24s backwards}
    .stack .s3{animation:fan-c .7s cubic-bezier(.22,.7,.3,1) .32s backwards}
  }
  @media (max-width:560px){
    .stack figure{animation:rise .5s ease backwards}
    .stack .s2{animation-delay:.08s}
    .stack .s3{animation-delay:.16s}
  }

  /* scroll reveal, containers only so the cards keep their own hover transforms */
  @supports (animation-timeline: view()){
    .band-head,.grid,.product,
    .specsheet,.about>div,.contact>*{
      animation:rise .9s linear both;
      animation-timeline:view();
      animation-range:entry 0% entry 42%;
    }
  }
}

/* hover feedback */
.navlinks a{position:relative}
.navlinks a::after{
  content:"";position:absolute;left:0;right:100%;bottom:-.3rem;height:1px;
  background:var(--rose);transition:right .25s ease;
}
.navlinks a:hover::after{right:0}

.item{transition:transform .25s ease,box-shadow .25s ease,border-color .25s ease}
.item:hover{transform:translateY(-4px);box-shadow:var(--lift);border-color:var(--rose)}
.shotwrap{overflow:hidden}
.shotwrap img{transition:transform .55s cubic-bezier(.22,.7,.3,1)}
.item:hover .shotwrap img{transform:scale(1.045)}

@media (min-width:561px){
  .stack figure{transition:transform .4s cubic-bezier(.22,.7,.3,1),box-shadow .4s ease}
  .stack:hover .s1{transform:rotate(-9deg) translate(-10px,-6px)}
  .stack:hover .s2{transform:rotate(8deg) translate(10px,-6px)}
  .stack:hover .s3{transform:rotate(-1.5deg) translateY(8px)}
}

.mailbox{transition:border-color .25s ease}
.mailbox:hover{border-color:var(--rose-soft)}

/* smooth jumps, offset so the sticky nav never covers a section heading */
html{scroll-behavior:smooth;scroll-padding-top:6.25rem}

@media (prefers-reduced-motion: reduce){
  html{scroll-behavior:auto}
  *{transition:none!important;animation:none!important}
}

/* Products dropdown. A little cut-out card that drops from the nav, same
   dashed edge and pink stock as the product sheets. Opens on hover and on
   keyboard focus, no script. */
.hasmenu{position:relative;display:inline-flex;align-self:stretch;align-items:center}
.caret{
  display:inline-block;width:0;height:0;margin-left:.34rem;vertical-align:middle;
  border-left:.26rem solid transparent;border-right:.26rem solid transparent;
  border-top:.3rem solid currentColor;transition:transform .22s ease;
}
.hasmenu:hover .caret,.hasmenu:focus-within .caret{transform:rotate(180deg)}
.menu{
  position:absolute;top:100%;left:-.85rem;z-index:3;
  margin-top:calc(var(--navpad) + .5rem);min-width:12.5rem;padding:.45rem;
  display:grid;gap:.1rem;text-transform:none;letter-spacing:0;
  font-family:var(--body);font-size:.88rem;
  background:var(--paper);border:1.5px dashed var(--cut);border-radius:.95rem;
  box-shadow:var(--lift);
  opacity:0;visibility:hidden;transform:translateY(-.4rem);
  transition:opacity .2s ease,transform .2s ease,visibility .2s;
}
/* bridges the gap so the panel survives the trip from the word to the card */
.menu::before{content:"";position:absolute;left:0;right:0;
  top:calc(-1 * (var(--navpad) + .5rem));height:calc(var(--navpad) + .5rem)}
.hasmenu:hover .menu,.hasmenu:focus-within .menu{opacity:1;visibility:visible;transform:none}
.menu a{
  display:block;padding:.5rem .7rem;border-radius:.6rem;
  color:var(--ink);text-decoration:none;white-space:nowrap;
  transition:background .18s ease,color .18s ease;
}
.menu a::after{display:none}
.menu a:hover,.menu a:focus-visible{background:var(--blush);color:var(--rose)}

/* Mobile menu. Below 900px the links row is hidden, so the same destinations
   come back as a sheet that drops out of the nav bar. */
.vh{
  position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0;
}
.burger{
  display:none;flex:none;align-items:center;justify-content:center;
  width:2.6rem;height:2.6rem;padding:0;margin-left:-.4rem;
  background:transparent;border:1.5px dashed var(--cut);border-radius:.7rem;
  color:var(--ink);cursor:pointer;transition:border-color .2s ease,background .2s ease;
}
.burger:hover{border-color:var(--rose);background:var(--blush)}
.bars{position:relative}
.bars,.bars::before,.bars::after{
  display:block;width:1.05rem;height:1.5px;border-radius:1px;
  background:currentColor;transition:transform .24s ease,opacity .18s ease;
}
.bars::before,.bars::after{content:"";position:absolute}
.bars::before{transform:translateY(-.34rem)}
.bars::after{transform:translateY(.34rem)}
.burger[aria-expanded="true"]{border-color:var(--rose);background:var(--blush);color:var(--rose)}
.burger[aria-expanded="true"] .bars{background:transparent}
.burger[aria-expanded="true"] .bars::before{transform:rotate(45deg)}
.burger[aria-expanded="true"] .bars::after{transform:rotate(-45deg)}

.mobilemenu{
  border-top:1px dashed var(--cut);
  background:var(--paper);
  box-shadow:var(--lift);
  animation:mmIn .22s cubic-bezier(.22,.7,.3,1);
  max-height:calc(100dvh - 5rem);overflow-y:auto;
}
@keyframes mmIn{from{opacity:0;transform:translateY(-.5rem)}to{opacity:1;transform:none}}
.mm-in{display:grid;gap:.1rem;padding-block:.9rem 1.2rem}
.mm-label{
  font-family:var(--spec);font-size:.68rem;letter-spacing:.14em;text-transform:uppercase;
  color:var(--rose);margin:.9rem 0 .3rem;
}
.mm-in>.mm-label:first-child{margin-top:0}
.mobilemenu a{
  display:block;padding:.62rem .7rem;border-radius:.6rem;
  color:var(--ink);text-decoration:none;font-size:1rem;
}
.mobilemenu a:hover,.mobilemenu a:focus-visible{background:var(--blush);color:var(--rose)}

@media (max-width:900px){.burger{display:inline-flex}}
/* above the breakpoint the real nav links are back, so the sheet never shows */
@media (min-width:901px){.mobilemenu{display:none!important}}

/* PayPal sits in the same dashed box as the email and number, but it is a real
   link, so it gets the rose underline the other two have no use for. */
.paylink{display:inline-block;text-decoration:none;color:var(--rose);user-select:auto}
.paylink:hover{border-color:var(--rose);text-decoration:underline;text-underline-offset:.2em}
