  :root{
    --red:#b3202c; --red-dark:#7d1620; --red-light:#e04452;
    --green:#14603c; --green-dark:#0d4429; --green-light:#1f7d50;
    --gold:#e8b64c; --gold-light:#f6d98a; --gold-deep:#b9862a;
    --cream:#fdf6e9; --ink:#2b1d18; --muted:#6f5b52;
    --card:#fffaf1; --shadow:0 10px 30px rgba(60,20,20,.18);
    --radius:18px;
  }
  *{box-sizing:border-box}
  html,body{margin:0;padding:0}
  body{
    font-family:"Segoe UI",system-ui,-apple-system,Roboto,Helvetica,Arial,sans-serif;
    color:var(--ink); font-size:18.5px; line-height:1.52;
    background:
      radial-gradient(1200px 600px at 50% -10%, #1d6f47 0%, #0d4429 45%, #08301d 100%);
    min-height:100vh; overflow-x:hidden;
  }
  /* ---------- background photographs (optional) ---------- */
  #bg{position:fixed;inset:0;z-index:-2;pointer-events:none;overflow:hidden}
  .bg-layer{
    position:absolute;inset:-2%;background-size:cover;background-position:center;
    opacity:0;transition:opacity 2.4s ease;
    transform:scale(1.04);
  }
  .bg-layer.on{opacity:1}
  /* a wash over the top so the text stays readable whatever the photo is */
  .bg-wash{
    position:absolute;inset:0;
    background:
      radial-gradient(120% 90% at 50% 0%, rgba(10,60,38,.30) 0%, rgba(8,48,29,.58) 55%, rgba(6,38,23,.78) 100%),
      linear-gradient(180deg, rgba(6,38,23,.22), rgba(6,38,23,.55));
  }
  body.has-bg{background:#08301d}

  /* ---------- snow ---------- */
  #snow{position:fixed;top:0;left:0;width:100vw;height:100vh;pointer-events:none;z-index:2;display:block}
  /* ---------- shell ---------- */
  .wrap{max-width:1000px;margin:0 auto;padding:0 18px 90px;position:relative;z-index:10}
/* the home page needs more room for its three columns; the other screens
   stay narrow so lines of text don't get uncomfortably long */
@media(min-width:1240px){
  .wrap{max-width:1400px}
  #s-list,#s-login{max-width:1000px;margin:0 auto}
}
  .screen{display:none;animation:fadeUp .35s ease both}
  .screen.active{display:block}
  @keyframes fadeUp{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}

  /* ---------- garland header ---------- */
  .garland{height:26px;background:
     radial-gradient(circle at 12px 4px, var(--red) 7px, transparent 8px),
     radial-gradient(circle at 36px 4px, var(--gold) 7px, transparent 8px),
     radial-gradient(circle at 60px 4px, #f2f2f2 7px, transparent 8px),
     radial-gradient(circle at 84px 4px, var(--green-light) 7px, transparent 8px);
     background-size:96px 26px; background-repeat:repeat-x;
     border-top:5px solid #0a3b23; position:relative; z-index:20;}

  header.top{
    display:flex;align-items:center;gap:14px;flex-wrap:wrap;
    padding:20px 18px; max-width:1000px;margin:0 auto;position:relative;z-index:20;
  }
  @media(min-width:1240px){header.top{max-width:1400px}}
@media(min-width:1560px){.wrap,header.top{max-width:1560px}}
  .brand{display:flex;align-items:center;gap:12px;margin-right:auto;text-decoration:none}
  .brand .tree{font-size:34px;filter:drop-shadow(0 3px 4px rgba(0,0,0,.4))}
  .brand h1{
    margin:0;font-size:clamp(20px,4.4vw,28px);letter-spacing:.5px;color:var(--gold-light);
    font-family:Georgia,"Times New Roman",serif;
    text-shadow:0 2px 0 var(--gold-deep),0 4px 12px rgba(0,0,0,.5);
  }
  .brand small{display:block;font-size:12px;color:#cfe6d6;letter-spacing:2px;text-transform:uppercase;font-family:inherit}

  .btn{
    font:inherit;font-weight:700;cursor:pointer;border:none;border-radius:999px;
    padding:12px 22px;min-height:48px;display:inline-flex;align-items:center;gap:9px;
    transition:transform .12s ease, box-shadow .12s ease, filter .12s;
    box-shadow:0 4px 0 rgba(0,0,0,.22), var(--shadow);
  }
  .btn:active{transform:translateY(3px);box-shadow:0 1px 0 rgba(0,0,0,.22)}
  .btn-red{background:linear-gradient(180deg,var(--red-light),var(--red));color:#fff}
  .btn-green{background:linear-gradient(180deg,var(--green-light),var(--green));color:#fff}
  .btn-gold{background:linear-gradient(180deg,var(--gold-light),var(--gold));color:#4a3208}
  .btn-ghost{background:rgba(255,255,255,.12);color:#fff;box-shadow:none;border:2px solid rgba(255,255,255,.35)}
  .btn-lg{font-size:19px;padding:16px 30px;min-height:58px}

  /* ---------- the music player ----------
     A proper little bar: play, skip either way, what's playing, and a
     line you can drag to move through the track. Sits in the header
     where the old Music button was. */
  .player{
    display:flex;align-items:center;gap:9px;
    background:rgba(6,38,23,.5);border:1px solid rgba(232,182,76,.28);
    border-radius:999px;padding:6px 14px 6px 8px;
    backdrop-filter:blur(3px);
  }
  .pbtn{
    flex:0 0 auto;display:grid;place-items:center;cursor:pointer;
    background:transparent;border:0;border-radius:50%;color:#f0e3c4;
    font-family:inherit;line-height:1;padding:0;
    transition:background .12s,transform .12s,opacity .12s;
    -webkit-tap-highlight-color:transparent;
  }
  .pbtn:hover{background:rgba(255,255,255,.12)}
  .pbtn:active{transform:scale(.9)}
  .pbtn:focus-visible{outline:2px solid var(--gold);outline-offset:2px}
  .pbtn-play{
    width:38px;height:38px;font-size:19px;
    background:rgba(232,182,76,.16);border:1px solid rgba(232,182,76,.4);
  }
  .pbtn-play:hover{background:rgba(232,182,76,.3)}
  .player.on .pbtn-play{background:var(--gold);border-color:var(--gold-light);color:#3a2a08}
  .pskip{width:28px;height:28px;font-size:13px;opacity:.72}
  .pskip:hover{opacity:1}
  .pbtn[disabled]{opacity:.28;cursor:default;pointer-events:none}

  .pmid{min-width:0;width:184px;display:flex;flex-direction:column;gap:4px}
  .ptrack{
    font-size:12px;letter-spacing:.6px;color:#cfe6d6;
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  }
  .player.on .ptrack{color:var(--gold-light)}

  /* the draggable line. Padded above and below so it is easy to grab
     without making the bar itself look thick. */
  .pbar{padding:5px 0;cursor:pointer;touch-action:none}
  .pbar-track{
    position:relative;height:4px;border-radius:3px;
    background:rgba(255,255,255,.16);
  }
  .pbar-fill{
    position:absolute;inset:0 auto 0 0;width:0;border-radius:3px;
    background:linear-gradient(90deg,var(--gold-deep),var(--gold-light));
  }
  .pbar-knob{
    position:absolute;top:50%;left:0;width:11px;height:11px;margin:-5.5px 0 0 -5.5px;
    border-radius:50%;background:#fff;box-shadow:0 1px 4px rgba(0,0,0,.5);
    opacity:0;transition:opacity .14s;
  }
  .pbar:hover .pbar-knob,.pbar.dragging .pbar-knob,.pbar:focus-visible .pbar-knob{opacity:1}
  .pbar:focus-visible{outline:2px solid var(--gold);outline-offset:3px;border-radius:4px}
  .player.seekless .pbar{display:none}
  .player.seekless .pmid{gap:0}

  .ptime{
    flex:0 0 auto;font-size:11px;color:#9fbfab;font-variant-numeric:tabular-nums;
    letter-spacing:.5px;min-width:34px;text-align:right;
  }
  .player.seekless .ptime{display:none}

  /* a phone has no room for the track line — play and skip is plenty */
  @media(max-width:700px){
    .player{gap:6px;padding:5px 10px 5px 6px}
    .pmid{width:110px}
    .pbar,.ptime{display:none}
  }

  /* ---------- login ---------- */
  .login-card{
    max-width:430px;margin:6vh auto 0;background:var(--card);border-radius:26px;
    padding:34px 30px 30px;box-shadow:var(--shadow);position:relative;
    border:3px solid var(--gold);
  }
  .login-card::before{
    content:"";position:absolute;inset:-3px -3px auto -3px;height:16px;border-radius:24px 24px 0 0;
    background:repeating-linear-gradient(90deg,var(--red) 0 18px,#fff 18px 36px);
  }
  .login-card h2{margin:16px 0 4px;font-family:Georgia,serif;font-size:27px;text-align:center;color:var(--green-dark)}
  .login-card p.sub{margin:0 0 22px;text-align:center;color:var(--muted);font-size:15px}
  label{display:block;font-weight:700;font-size:15px;margin:14px 0 6px;color:var(--green-dark)}
  input[type=text],input[type=password],input[type=url],textarea,select{
    width:100%;font:inherit;padding:14px 16px;border-radius:14px;border:2px solid #e3d5bf;
    background:#fff;min-height:52px;color:var(--ink);
  }
  input:focus,textarea:focus{outline:none;border-color:var(--green-light);box-shadow:0 0 0 4px rgba(31,125,80,.15)}
  .hint{font-size:13px;color:var(--muted);margin-top:6px}
  .center{text-align:center}
  .demo-note{
    margin-top:18px;padding:12px 14px;border-radius:12px;background:#fff3d6;border:1px dashed var(--gold-deep);
    font-size:14px;color:#6b5115;
  }

  /* ---------- family grid ---------- */
  .section-title{
    color:var(--gold-light);font-family:Georgia,serif;font-size:clamp(22px,4vw,30px);
    margin:10px 0 4px;text-shadow:0 2px 8px rgba(0,0,0,.5);
  }
  .section-sub{color:#d6ead9;margin:0 0 22px;font-size:15px}
  .family{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:16px}
  .person{
    background:var(--card);border-radius:var(--radius);padding:20px 16px;text-align:center;
    cursor:pointer;border:3px solid transparent;box-shadow:var(--shadow);
    transition:transform .15s, border-color .15s;
  }
  .person:hover{transform:translateY(-4px);border-color:var(--gold)}
  .avatar{
    width:74px;height:74px;border-radius:50%;margin:0 auto 10px;display:grid;place-items:center;
    font-size:32px;color:#fff;font-weight:700;font-family:Georgia,serif;
    box-shadow:inset 0 -6px 12px rgba(0,0,0,.18);
  }
  .person h3{margin:0;font-size:19px;color:var(--green-dark)}
  .person .count{font-size:14px;color:var(--muted);margin-top:3px}
  .person .me{display:inline-block;margin-top:8px;font-size:11px;letter-spacing:1px;text-transform:uppercase;
    background:var(--gold);color:#4a3208;border-radius:99px;padding:3px 10px;font-weight:800}

  /* ---------- wishlist ---------- */
  .list-head{display:flex;align-items:center;gap:16px;flex-wrap:wrap;margin-bottom:18px}
  .list-head .avatar{margin:0;width:64px;height:64px;font-size:27px}
  .list-head h2{margin:0;color:var(--gold-light);font-family:Georgia,serif;font-size:clamp(22px,4.4vw,30px)}
  .list-head .who{color:#d6ead9;font-size:14px;margin-top:2px}

  .items{display:grid;gap:14px}
  .item{
    background:var(--card);border-radius:var(--radius);box-shadow:var(--shadow);
    display:flex;gap:16px;padding:18px;align-items:flex-start;border-left:8px solid var(--green);
  }
  .item.claimed{border-left-color:var(--gold-deep)}
  .item .emoji{
    font-size:44px;line-height:1;flex:0 0 auto;width:64px;height:64px;border-radius:16px;
    display:grid;place-items:center;background:#fff;box-shadow:inset 0 0 0 2px #eadfc8;
  }
  .item .body{flex:1;min-width:0}
  .item h4{margin:0 0 6px;font-size:19px;line-height:1.3}
  .item .note{color:var(--muted);font-size:15px;margin:4px 0 0}
  .linkcard{
    display:inline-flex;align-items:center;gap:9px;margin-top:10px;text-decoration:none;
    background:#fff;border:2px solid #e3d5bf;border-radius:12px;padding:9px 14px;
    color:var(--green-dark);font-weight:700;font-size:15px;max-width:100%;
  }
  .linkcard:hover{border-color:var(--green-light);background:#f4fbf6}
  .linkcard .favicon{width:26px;height:26px;border-radius:7px;display:grid;place-items:center;
    font-size:13px;font-weight:800;color:#fff;background:var(--green-light);flex:0 0 auto}
  .linkcard .arrow{color:var(--muted);font-weight:400}
  .thumb{
    margin-top:10px;width:132px;height:96px;border-radius:12px;border:2px solid #e3d5bf;
    display:grid;place-items:center;font-size:12px;color:var(--muted);text-align:center;padding:6px;
    background:repeating-linear-gradient(45deg,#f3ece0 0 10px,#eee3d2 10px 20px);
  }
  .meta{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-top:12px}
  .chip{font-size:13px;background:#eef4ee;color:var(--green-dark);border-radius:99px;padding:5px 12px;font-weight:600}
  .chip.price{background:#fdf0d6;color:#6b5115}
  .chip.claimed{background:var(--gold);color:#4a3208;font-weight:800}
  .claimbtn{font-size:14px;padding:9px 16px;min-height:42px}
  .secret{
    margin-top:12px;font-size:14px;background:#fff8e6;border:1px dashed var(--gold-deep);
    border-radius:12px;padding:10px 12px;color:#6b5115;
  }
  .owner-banner{
    background:rgba(255,255,255,.12);border:2px dashed rgba(255,255,255,.4);color:#eafaee;
    border-radius:14px;padding:14px 16px;margin-bottom:18px;font-size:15px;
  }

  /* ---------- big add button ---------- */
  .addbar{position:sticky;bottom:0;padding:14px 0 20px;z-index:30;
    background:linear-gradient(180deg,transparent,rgba(8,48,29,.85) 45%)}
  .addbar .btn{width:100%;justify-content:center;font-size:20px}

  /* ---------- modal ---------- */
  .modal{position:fixed;inset:0;background:rgba(6,30,18,.72);z-index:80;display:none;
    align-items:flex-end;justify-content:center;padding:0}
  .modal.open{display:flex}
  @media(min-width:640px){.modal{align-items:center;padding:24px}}
  .sheet{
    background:var(--cream);width:100%;max-width:560px;border-radius:24px 24px 0 0;
    padding:22px 20px 26px;max-height:92vh;overflow:auto;box-shadow:var(--shadow);
    animation:slideUp .28s ease both;
  }
  @media(min-width:640px){.sheet{border-radius:24px}}
  @keyframes slideUp{from{transform:translateY(40px);opacity:0}to{transform:none;opacity:1}}
  .sheet h3{margin:0 0 4px;font-family:Georgia,serif;font-size:24px;color:var(--green-dark)}
  .sheet .lead{margin:0 0 4px;color:var(--muted);font-size:15px}
  .bigfield{font-size:18px !important;min-height:64px !important;padding:18px !important}
  .detect{margin-top:8px;font-size:14px;font-weight:700;min-height:22px}
  .detect.link{color:var(--green)}
  .detect.text{color:var(--muted);font-weight:500}

  /* 125 icons would make the add-a-gift sheet enormous, so the grid gets a
     height and scrolls, the same way the food picker does */
  .emoji-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(54px,1fr));gap:8px;margin-top:8px;
    max-height:212px;overflow-y:auto;padding-right:4px}
  .emoji-opt{
    font-size:26px;line-height:1;background:#fff;border:2px solid #e3d5bf;border-radius:14px;
    min-height:54px;cursor:pointer;display:grid;place-items:center;transition:transform .1s,border-color .1s;
    -webkit-tap-highlight-color:transparent;
  }
  .emoji-opt:hover{transform:scale(1.08)}
  .emoji-opt.sel{border-color:var(--red);background:#ffeaec;box-shadow:0 0 0 3px rgba(179,32,44,.18);transform:scale(1.08)}

  details.extras{margin-top:18px;border-top:2px dashed #e3d5bf;padding-top:14px}
  details.extras summary{cursor:pointer;font-weight:700;color:var(--green-dark);font-size:16px;min-height:44px;display:flex;align-items:center;gap:8px}
  .drop{
    margin-top:10px;border:3px dashed #cdbfa5;border-radius:16px;background:#fff;
    padding:24px 16px;text-align:center;color:var(--muted);cursor:pointer;
  }
  .drop:hover{border-color:var(--green-light);background:#f6fbf7;color:var(--green-dark)}
  .drop .ic{font-size:34px;display:block;margin-bottom:6px}
  .sheet-actions{display:flex;gap:10px;margin-top:22px}
  .sheet-actions .btn{flex:1;justify-content:center}

  .toast{
    position:fixed;left:50%;bottom:26px;transform:translateX(-50%) translateY(120px);
    background:var(--green-dark);color:#fff;padding:14px 22px;border-radius:99px;z-index:100;
    box-shadow:var(--shadow);font-weight:700;transition:transform .3s ease;
  }
  .toast.show{transform:translateX(-50%) translateY(0)}
  footer{text-align:center;color:#9fc4ab;font-size:13px;padding:26px 18px 40px;position:relative;z-index:10}

/* ---- extras used by the live app ---- */
.err{color:var(--red);font-weight:700;font-size:15px;margin-top:12px;min-height:20px}
.item .del{background:none;border:none;color:var(--muted);cursor:pointer;font-size:14px;
  padding:6px 10px;border-radius:8px;min-height:38px}
.item .del:hover{background:#f7ece0;color:var(--red)}
.empty{background:rgba(255,255,255,.1);border:2px dashed rgba(255,255,255,.35);color:#eafaee;
  border-radius:16px;padding:34px 20px;text-align:center;font-size:17px}
.loading{color:#cfe6d6;text-align:center;padding:40px;font-size:17px}

/* ---------- home: activity feed + chat ---------- */
/* phones: stream first, menus after */
.home-grid{display:grid;gap:18px;grid-template-columns:1fr}
.menucol,.maincol{display:flex;flex-direction:column;gap:18px;min-width:0}

/* wide: the stream takes the room, menus sit down the right */
@media(min-width:1000px){
  .home-grid{grid-template-columns:minmax(0,1.9fr) minmax(330px,400px);align-items:start}
}

/* ---------- the stream panel ---------- */
.panel{background:var(--card);border-radius:var(--radius);box-shadow:var(--shadow);
  padding:16px 16px 14px;display:flex;flex-direction:column;min-height:0}
.panel-title{margin:0 0 12px;font-family:Georgia,serif;font-size:19px;color:var(--green-dark);
  border-bottom:2px dashed #e3d5bf;padding-bottom:10px}

.chatbox{margin-top:12px;border-top:2px dashed #e3d5bf;padding-top:12px}
.chatbox textarea{min-height:56px;font-size:16px;padding:11px 13px}
.chatrow{display:flex;gap:10px;align-items:center;margin-top:9px;flex-wrap:wrap}
.chatrow .btn{margin-left:auto;min-height:46px}
.secretpick{font-size:14px;font-weight:700;color:var(--muted);display:flex;align-items:center;
  gap:7px;margin:0}
.secretpick select{width:auto;min-height:44px;padding:8px 11px;font-size:15px;border-radius:11px}
.secret-note{font-size:13px;color:var(--gold-deep);font-weight:700;margin-top:8px;min-height:18px}
.chat-empty{color:var(--muted);font-size:15px;text-align:center;padding:24px 10px}

.msg .dot{width:32px;height:32px;border-radius:50%;flex:0 0 auto;display:grid;place-items:center;
  color:#fff;font-weight:700;font-size:14px;font-family:Georgia,serif}
.msg .bub{max-width:100%;word-wrap:break-word;overflow-wrap:anywhere}
.msg.mine{flex-direction:row-reverse}
.msg .who{font-size:12px;color:var(--muted);font-weight:700;margin-bottom:2px}
.msg .hid{font-size:12px;color:var(--gold-deep);font-weight:700;margin-top:4px}
.msg .rm{background:none;border:none;color:#c4b49c;cursor:pointer;font-size:15px;padding:2px 6px;
  align-self:center}
.msg .rm:hover{color:var(--red)}

/* =========================================================
   THE MENUS — deliberately NOT like the feed/chat panels.
   These are meant to read as printed cards on paper: white,
   squared off, serif, centred, with a script heading.
   ========================================================= */
/* transparent: the green shows through, so these read as printed cards
   pinned to the page rather than solid boxes like the stream panel */
.menucard{
  background:rgba(7,42,26,.42);
  border-radius:3px;                       /* squared off, not rounded */
  box-shadow:none;
  padding:0;display:flex;min-height:0;position:relative;
  backdrop-filter:blur(3px);
}
/* a thin double rule just inside the edge, like a printed border */
.menucard::before{
  content:"";position:absolute;inset:9px;border:1px solid rgba(232,182,76,.55);
  border-radius:1px;pointer-events:none;
}
.menucard::after{
  content:"";position:absolute;inset:13px;border:1px solid rgba(232,182,76,.25);
  border-radius:1px;pointer-events:none;
}
.menucard-inner{
  flex:1;display:flex;flex-direction:column;min-height:0;
  padding:26px 20px 20px;position:relative;z-index:1;
  font-family:Georgia,"Iowan Old Style","Times New Roman",serif;
}

.menu-head{text-align:center;margin-bottom:6px}
.menu-orn{display:none}
.menu-head h3{
  margin:0;font-family:'Great Vibes',cursive;font-weight:400;
  font-size:34px;line-height:1.05;color:var(--gold-light);letter-spacing:.5px;
  text-shadow:0 2px 10px rgba(0,0,0,.45);
}
.menu-sub{
  font-size:10px;letter-spacing:3.4px;text-transform:uppercase;color:#a8c9b4;
  margin-top:5px;font-family:Georgia,serif;
}
.menu-head::after{
  content:"";display:block;width:34px;height:1px;background:var(--gold);margin:12px auto 0;
}

.menu-scroll{flex:1;overflow-y:auto;min-height:80px;padding:0 2px}

.course{margin-top:16px}
.course h4{
  margin:0 0 4px;font-family:Georgia,serif;font-size:11px;letter-spacing:3.2px;
  text-transform:uppercase;color:#8fd6ac;text-align:center;font-weight:700;
}
.course h4::before,.course h4::after{content:"— ";color:rgba(232,182,76,.55);letter-spacing:0}
.course h4::after{content:" —"}

/* each dish: centred, serif, description under it, name of the cook in tiny caps */
.dish{display:block;text-align:center;padding:9px 2px 8px;position:relative}
.dish + .dish{border-top:1px dotted rgba(255,255,255,.16)}
.dish .em{font-size:19px;line-height:1;display:block;margin-bottom:2px}
.dish .nm{font-size:17px;line-height:1.25;color:#fdf6e9;display:block}
.dish .dn{font-size:12.5px;line-height:1.35;color:#bcd6c5;margin-top:2px;font-style:italic}
.dish .who{
  display:block;margin-top:4px;font-size:9.5px;letter-spacing:2.2px;
  text-transform:uppercase;color:#a3bfae;
}
.dish .dots{display:none}
.dish .x{
  position:absolute;top:6px;right:0;background:none;border:none;color:rgba(255,255,255,.3);
  cursor:pointer;font-size:13px;padding:3px 5px;border-radius:5px;line-height:1;
}
.dish:hover .x{color:var(--red-light)}
.dish .x:hover{background:rgba(255,255,255,.12)}
.menu-empty{
  text-align:center;color:#a8c9b4;font-size:15px;padding:22px 8px;font-style:italic;
  font-family:Georgia,serif;line-height:1.5;
}

/* the add box: kept plain so it reads as a form, not part of the printed card */
.menu-add{
  margin-top:14px;padding-top:13px;flex:0 0 auto;
  border-top:1px solid rgba(232,182,76,.4);
  font-family:"Segoe UI",system-ui,sans-serif;
}
.menu-add-title{
  font-family:Georgia,serif;font-size:10px;letter-spacing:2.6px;text-transform:uppercase;
  color:#a8c9b4;text-align:center;margin-bottom:9px;
}
.menu-add input,.menu-add select{border-radius:6px;border-color:#e0d2b6}

/* breakfast: same paper, green ink instead of red */
.breakfastcard{background:rgba(10,50,32,.42)}
.breakfastcard::before{border-color:rgba(143,214,172,.5)}
.breakfastcard::after{border-color:rgba(143,214,172,.2)}
.breakfastcard .menucard-inner{padding:26px 15px 18px}
.breakfastcard .menu-head h3{color:#b8ecca;font-size:28px}
.breakfastcard .menu-head::after{background:#8fd6ac}
.breakfastcard .course h4{display:none}
.breakfastcard .dish .nm{font-size:16px}
.breakfastcard .menu-add{border-top-color:rgba(143,214,172,.4)}
.breakfastcard .dish + .dish{border-top-color:rgba(143,214,172,.2)}

/* suggestions */
.suggestbox .sugg-lead{margin:0 0 12px;font-size:14px;color:var(--muted);line-height:1.45}
.suggestbox textarea{font-size:15px}
.sugg-note{font-size:13px;font-weight:700;color:var(--green);margin-top:9px;min-height:18px}
.sugg-item{background:#fff;border:2px solid #eadfc8;border-radius:12px;padding:10px 12px;
  margin-bottom:9px;font-size:15px}
.sugg-item.new{border-color:var(--gold);background:#fffaec}
.sugg-item .meta{font-size:12px;color:var(--muted);font-weight:700;margin-bottom:4px;
  display:flex;gap:8px;align-items:center}
.sugg-item .acts{margin-top:7px;display:flex;gap:7px}
.sugg-item .acts button{background:none;border:2px solid #e3d5bf;border-radius:9px;
  font:inherit;font-size:13px;padding:5px 11px;cursor:pointer;color:var(--muted);min-height:34px}
.sugg-item .acts button:hover{border-color:var(--green-light);color:var(--green-dark)}
.sugg-count{background:var(--red);color:#fff;border-radius:99px;font-size:12px;
  padding:2px 9px;margin-left:7px;font-weight:800}
#suggInbox{max-height:260px;overflow-y:auto;margin-bottom:12px}

/* the smaller Christmas-morning card */
.breakfastcard .menucard-inner{border-color:var(--green-light);padding:16px 13px 13px}
.breakfastcard .menu-orn{color:var(--green-light)}
.breakfastcard .menu-head h3{font-size:19px;color:var(--green-dark)}
.breakfastcard .menu-head::after{background:var(--green-light);width:42px}

.breakfastcard .course h4{display:none}   /* only one section here */

.breakfastcard .menu-add{border-top-color:#cfe0d3}

/* small header link */
.topbtn{background:none;border:none;font:inherit;font-size:14px;font-weight:700;
  color:#cfe6d6;cursor:pointer;padding:9px 12px;border-radius:10px;display:inline-flex;
  align-items:center;gap:6px;min-height:42px;text-decoration:underline;
  text-decoration-color:rgba(255,255,255,.28);text-underline-offset:4px}
.topbtn:hover{color:#fff;background:rgba(255,255,255,.1)}
.sheet.suggestbox h3{margin-bottom:6px}
.sheet.suggestbox .sugg-count{vertical-align:middle}

/* ---------- food emoji picker + bigger emoji on the menu ---------- */
.food-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(34px,1fr));
  gap:5px;margin-top:9px;max-height:106px;overflow-y:auto}
.food-opt{font-size:18px;line-height:1;background:#fff;border:2px solid #e3d5bf;border-radius:9px;
  min-height:34px;cursor:pointer;display:grid;place-items:center;padding:0;
  transition:transform .1s,border-color .1s;-webkit-tap-highlight-color:transparent}
.food-opt:hover{transform:scale(1.12)}
.food-opt.sel{border-color:var(--red);background:#ffeaec;transform:scale(1.12);
  box-shadow:0 0 0 2px rgba(179,32,44,.18)}
.breakfastcard .food-opt.sel{border-color:var(--green);background:#e9f5ec;
  box-shadow:0 0 0 2px rgba(20,96,60,.18)}

/* the emoji beside each dish — deliberately larger than the text */


/* =========================================================
   THE FULL MENU — a proper printed Christmas menu
   ========================================================= */
.viewfull{
  width:100%;margin-top:12px;background:none;border:none;cursor:pointer;
  font-family:Georgia,serif;font-size:14px;letter-spacing:2px;
  text-transform:uppercase;color:var(--gold-deep);padding:9px;border-radius:9px;min-height:40px}
.viewfull:hover{background:#fdf1d9;color:var(--red)}
.dishnote{margin-top:7px;font-size:14px !important;min-height:42px !important;padding:9px 12px !important}

.fullmenu{position:fixed;inset:0;z-index:90;background:#4a1418;overflow-y:auto;display:none;
  padding:0 0 40px}
.fullmenu.open{display:block}
.fm-bar{position:sticky;top:0;z-index:5;display:flex;gap:10px;justify-content:space-between;
  padding:14px 18px;background:linear-gradient(#4a1418,rgba(74,20,24,.85))}

.fm-page{
  max-width:660px;margin:0 auto;background:#fff;position:relative;
  padding:74px 54px 64px;box-shadow:0 20px 60px rgba(0,0,0,.45);
  font-family:Georgia,"Iowan Old Style","Times New Roman",serif;color:#2b1d18;
}
/* the decorated corners */
.fm-corner{position:absolute;width:180px;height:180px;pointer-events:none;opacity:.95}
.fm-corner.tl{top:0;left:0}
.fm-corner.tr{top:0;right:0;transform:scaleX(-1)}
.fm-corner.bl{bottom:0;left:0;transform:scaleY(-1)}
.fm-corner.br{bottom:0;right:0;transform:scale(-1,-1)}

.fm-script{font-family:"Great Vibes",cursive;font-size:66px;line-height:.95;color:#c0202c;
  text-align:center;margin:0}
.fm-title{text-align:center;font-size:24px;letter-spacing:7px;text-transform:uppercase;
  font-weight:700;color:#3a2419;margin:10px 0 0}
.fm-sub{text-align:center;font-size:13px;letter-spacing:3px;text-transform:uppercase;
  color:#9a8778;margin:12px 0 0}

.fm-rule{display:flex;align-items:center;justify-content:center;gap:11px;margin:26px 0 20px}
.fm-rule i{display:block;height:1px;width:64px;background:linear-gradient(90deg,transparent,#c9a227)}
.fm-rule i:last-child{background:linear-gradient(270deg,transparent,#c9a227)}
.fm-rule span{color:#c9a227;font-size:15px;line-height:1}

.fm-course{text-align:center;font-size:21px;letter-spacing:5px;text-transform:uppercase;
  font-weight:700;color:#14603c;margin:0}
.fm-course.alt{color:#c0202c}
.fm-dish{text-align:center;margin:17px 0 0}
.fm-dish .d{font-size:25px;font-weight:600;line-height:1.25}
.fm-dish .n{font-size:15px;color:#6f5b52;margin-top:3px;line-height:1.4;
  max-width:430px;margin-left:auto;margin-right:auto}
.fm-dish .by{font-size:12px;letter-spacing:2.5px;text-transform:uppercase;color:#b3a294;margin-top:5px}
.fm-foot{text-align:center;font-size:13px;letter-spacing:2.5px;text-transform:uppercase;
  color:#9a8778;margin-top:44px;padding-top:20px;border-top:1px solid #eadfc8}
.fm-empty{text-align:center;color:#9a8778;font-size:19px;padding:40px 0;font-style:italic}

@media(max-width:640px){
  .fm-page{padding:52px 26px 46px;box-shadow:none}
  .fm-script{font-size:48px}
  .fm-title{font-size:19px;letter-spacing:5px}
  .fm-dish .d{font-size:21px}
  .fm-corner{width:118px;height:118px}
}

/* printing: just the menu, no dark surround, no buttons */


/* ---------- the menus now have room, so dress them properly ---------- */

/* the drawn corners, now shown on the real page */
.menucard .mc-corner{position:absolute;width:118px;height:118px;pointer-events:none;z-index:0;opacity:.9}
.menucard .mc-corner.tl{top:2px;left:2px}
.menucard .mc-corner.tr{top:2px;right:2px;transform:scaleX(-1)}
.breakfastcard .mc-corner{width:96px;height:96px}

.viewfull{
  width:auto;margin:14px auto 0;display:block;background:none;border:none;cursor:pointer;
  font-family:Georgia,serif;font-size:11px;letter-spacing:2.6px;text-transform:uppercase;
  color:#bbab99;padding:8px 14px;border-radius:6px;min-height:36px}
.viewfull:hover{color:#b3202c;background:#faf0e2}


/* print: just the two menus, nothing else */


/* the add row, balanced */
.menu-addrow{display:flex;gap:9px;margin-top:10px;align-items:stretch}
.menu-addrow select{flex:1;min-height:46px}
.menu-addrow .btn{min-height:46px;padding:10px 26px;flex:0 0 auto}
.food-grid{grid-template-columns:repeat(auto-fill,minmax(36px,1fr));max-height:88px}

/* ---------- the one stream: activity + chat together ---------- */
.streampanel{min-height:520px}
.stream{
  flex:1;overflow-y:auto;max-height:min(62vh,620px);min-height:280px;
  display:flex;flex-direction:column;gap:3px;padding-right:4px;
}
.streampanel .chatbox{margin-top:12px}

/* an event the site itself reports */
.ev{display:flex;gap:11px;align-items:flex-start;padding:8px 6px;border-radius:11px;line-height:1.4}
.ev .dot{width:30px;height:30px;border-radius:50%;flex:0 0 auto;display:grid;place-items:center;
  color:#fff;font-weight:700;font-size:13px;font-family:Georgia,serif}
.ev .txt{flex:1;font-size:14.5px;min-width:0;color:#6f5b52}
.ev .txt b{color:var(--green-dark)}
.ev .gift{display:inline-flex;align-items:center;gap:5px;background:#eef4ee;border-radius:8px;
  padding:1px 8px;margin-top:3px;font-size:14px;max-width:100%;color:var(--ink)}
.ev .when{font-size:11.5px;color:#b3a294;white-space:nowrap;padding-top:4px}
.ev.claim .txt b{color:var(--gold-deep)}

/* a message someone typed — given more weight than an event */
.msg{display:flex;gap:10px;align-items:flex-start;padding:3px 2px}
.msg .bub{background:#fff;border:2px solid #eadfc8;border-radius:14px;padding:9px 14px;font-size:15.5px}
.msg.mine .bub{background:#eef7f0;border-color:#c8e2d1}

/* a soft divider when the day changes */
.daysep{display:flex;align-items:center;gap:10px;margin:12px 2px 6px;color:#b3a294;
  font-size:11px;letter-spacing:2.4px;text-transform:uppercase}
.daysep i{flex:1;height:1px;background:#e9ddc8;display:block}

/* menus: tighter, since they're a sidebar again */
.menucard-inner{padding:30px 22px 20px}
.menu-head h3{font-size:36px}
.breakfastcard .menu-head h3{font-size:30px}
.menu-scroll{max-height:none;overflow:visible}
.dish{padding:11px 2px 10px}
.dish .em{font-size:21px;margin-bottom:3px}
.dish .nm{font-size:18px}
.dish .dn{font-size:13px}
.menucard .mc-corner{width:92px;height:92px;opacity:.85}

@media(max-width:640px){
  .menucard-inner{padding:26px 17px 18px}
  .menu-head h3{font-size:32px}
  .menucard .mc-corner{width:74px;height:74px}
  .stream{max-height:none}
}



/* ---------- everyone's lists, sitting under the stream ---------- */
.peoplebox{
  background:var(--card);border-radius:var(--radius);box-shadow:var(--shadow);
  padding:16px 16px 18px;
}
.peoplebox .panel-title{margin-bottom:14px}
.peoplebox .family{grid-template-columns:repeat(auto-fill,minmax(132px,1fr));gap:12px}
.peoplebox .person{padding:15px 10px;border-width:2px}
.peoplebox .avatar{width:54px;height:54px;font-size:23px;margin-bottom:8px}
.peoplebox .person h3{font-size:16px}
.peoplebox .person .count{font-size:13px}
.peoplebox .person .me{font-size:10px;padding:2px 8px;margin-top:6px}

/* ---------- baubles hanging down the empty margins ---------- */
.sidehang{
  position:fixed;top:0;width:190px;height:min(70vh,700px);
  pointer-events:none;z-index:0;display:none;opacity:.95;
  /* they fade out before they reach the foot of the page */
  -webkit-mask-image:linear-gradient(to bottom,#000 62%,rgba(0,0,0,.6) 82%,transparent 100%);
  mask-image:linear-gradient(to bottom,#000 62%,rgba(0,0,0,.6) 82%,transparent 100%);
}
.sidehang svg{width:100%;height:100%;display:block;overflow:visible}
#sideL{left:0}
#sideR{right:0}
/* only once there's actually margin to fill */
@media(min-width:1720px){.sidehang{display:block}}
@media(min-width:1900px){.sidehang{width:210px}}


/* each strand swings from where it's pinned at the top */
.strand{transform-box:fill-box;transform-origin:top center;animation:sway 6s ease-in-out infinite}
@keyframes sway{
  0%,100%{transform:rotate(-1.6deg)}
  50%{transform:rotate(1.6deg)}
}
@media (prefers-reduced-motion:reduce){.strand{animation:none}}

/* more room means the stream can breathe */
@media(min-width:1240px){
  .stream{max-height:min(66vh,700px)}
  .ev .txt{font-size:15.5px}
  .msg .bub{font-size:16px}
  .menu-head h3{font-size:40px}
  .breakfastcard .menu-head h3{font-size:33px}
  .dish .nm{font-size:19px}
  .dish .dn{font-size:13.5px}
  .peoplebox .family{grid-template-columns:repeat(auto-fill,minmax(146px,1fr))}
  .peoplebox .avatar{width:60px;height:60px;font-size:25px}
  .peoplebox .person h3{font-size:17px}
}

/* ---------- everything a notch larger (matches ~110% browser zoom) ---------- */
.brand h1{font-size:clamp(22px,4.6vw,31px)}
.brand small{font-size:13px}
.brand .tree{font-size:37px}
.btn{font-size:17px;padding:13px 24px;min-height:52px}
.btn-lg{font-size:21px;padding:17px 32px;min-height:62px}
.topbtn{font-size:15px;min-height:46px}
.player .ptrack{font-size:13px}

.panel-title{font-size:21px}
.ev .txt{font-size:16px}
.ev .gift{font-size:15px}
.ev .when{font-size:12.5px}
.ev .dot{width:33px;height:33px;font-size:14px}
.msg .bub{font-size:17px;padding:10px 15px}
.msg .who{font-size:13px}
.msg .dot{width:35px;height:35px;font-size:15px}
.daysep{font-size:12px}
.chatbox textarea{font-size:17px;min-height:62px}
.secretpick{font-size:15px}
.secretpick select{font-size:16px;min-height:47px}

.section-title{font-size:clamp(24px,4.2vw,32px)}
.person h3{font-size:20px}
.person .count{font-size:15px}
.item h4{font-size:21px}
.item .note{font-size:16px}
.linkcard{font-size:16px}
.chip{font-size:14px}
.owner-banner{font-size:16px}

input[type=text],input[type=password],textarea,select{font-size:17px;min-height:55px}
.bigfield{font-size:19px !important;min-height:68px !important}
label{font-size:16px}
.emoji-opt{font-size:28px;min-height:58px}
.food-opt{font-size:19px;min-height:36px}

@media(min-width:1240px){
  .menu-head h3{font-size:43px}
  .breakfastcard .menu-head h3{font-size:35px}
  .dish .nm{font-size:20.5px}
  .dish .dn{font-size:14.5px}
  .dish .em{font-size:23px}
  .course h4{font-size:12.5px}
  .menu-sub{font-size:11px}
}

/* the date on each menu */
.menu-date{
  font-family:Georgia,serif;font-size:15px;letter-spacing:1.4px;color:var(--gold);
  margin-top:7px;
}
.menu-date sup{font-size:.62em;letter-spacing:0;margin-left:1px}
.breakfastcard .menu-date{color:#8fd6ac}
@media(min-width:1240px){.menu-date{font-size:16px}}

/* ---------- the countdown under the title ---------- */
.countdown{
  display:flex;align-items:baseline;gap:7px;flex-wrap:wrap;
  margin-top:4px;font-family:Georgia,serif;
}
.cd-unit{display:inline-flex;align-items:baseline;gap:3px}
.cd-num{
  font-size:20px;font-weight:700;color:var(--gold-light);line-height:1;
  font-variant-numeric:tabular-nums;
  text-shadow:0 1px 0 var(--gold-deep),0 2px 8px rgba(0,0,0,.45);
}
.cd-lab{font-size:10.5px;letter-spacing:2px;text-transform:uppercase;color:#a8c9b4}
.cd-dot{color:rgba(232,182,76,.5);font-size:13px;line-height:1}
.cd-tail{font-size:10.5px;letter-spacing:2px;text-transform:uppercase;color:#a8c9b4;margin-left:2px}
.cd-loading{font-size:12px;letter-spacing:2px;text-transform:uppercase;color:#cfe6d6}
.cd-day{
  font-family:'Great Vibes',cursive;font-size:26px;color:var(--gold-light);line-height:1;
  text-shadow:0 2px 10px rgba(0,0,0,.5);
}
@media(max-width:640px){
  .countdown{gap:5px}
  .cd-num{font-size:17px}
  .cd-lab,.cd-tail{font-size:9px;letter-spacing:1.4px}
}

/* =========================================================
   PRINTING — just the two menus, on white paper.
   Everything else is hidden: the stream, the family list,
   the header, the scenery and the add-a-dish forms.
   ========================================================= */
@media print{
  @page{margin:14mm}
  html,body{background:#fff !important}
  #snow,.sidehang,.garland,header.top,
  .streampanel,.peoplebox,.section-title,.section-sub,.family,
  footer,.toast,.modal,.menu-add,.viewfull,.dish .x,.mc-corner{
    display:none !important;
  }
  .wrap{max-width:none !important;padding:0 !important;margin:0 !important}
  .screen{display:none !important}
  .screen.active{display:block !important}
  .home-grid{display:block !important}
  .maincol{display:none !important}
  .menucol{display:block !important}

  /* the cards become printed pages: white, dark ink, no glass effects */
  .menucard{
    background:#fff !important;backdrop-filter:none !important;
    box-shadow:none !important;break-inside:avoid;page-break-inside:avoid;
    margin:0 0 16mm 0 !important;width:100% !important;display:block !important;
  }
  .menucard::before{border-color:#c9a227 !important}
  .menucard::after{border-color:#e6d5a8 !important}
  .menucard-inner{display:block !important;padding:14mm 12mm 10mm !important}
  .menu-scroll{max-height:none !important;overflow:visible !important;display:block !important}

  .menu-head h3{color:#b3202c !important;text-shadow:none !important;font-size:40pt !important}
  .breakfastcard .menu-head h3{color:#14603c !important;font-size:32pt !important}
  .menu-date{color:#a8811b !important}
  .breakfastcard .menu-date{color:#14603c !important}
  .menu-sub{color:#8a7768 !important}
  .menu-head::after{background:#c9a227 !important}
  .course h4{color:#14603c !important;font-size:11pt !important}
  .course h4::before,.course h4::after{color:#d8c9a4 !important}
  .dish{page-break-inside:avoid}
  .dish + .dish{border-top-color:#ece0c6 !important}
  .dish .nm{color:#2b1d18 !important;font-size:15pt !important}
  .dish .dn{color:#6f5b52 !important;font-size:10.5pt !important}
  .dish .who{color:#a1907f !important;font-size:8pt !important}

  /* whichever card's print link was used, only that one goes to paper */
  body.print-supper .breakfastcard{display:none !important}
  body.print-breakfast .menucard:not(.breakfastcard){display:none !important}
}

/* =========================================================
   COUNTDOWN BAR — picks up more decoration the closer it gets
   ========================================================= */
.cdbar{margin-top:9px;max-width:420px}
.cdbar-track{
  position:relative;height:12px;border-radius:99px;
  background:rgba(0,0,0,.28);box-shadow:inset 0 1px 3px rgba(0,0,0,.35);
  border:1px solid rgba(255,255,255,.1);
}
.cdbar-fill{
  position:absolute;inset:1px auto 1px 1px;border-radius:99px;
  background:var(--green-light);
  transition:width .8s ease, background .8s ease;
  overflow:hidden;
}
.cdbar-lights,.cdbar-snow{position:absolute;inset:0;display:block;opacity:0;transition:opacity .6s}
.cdbar-head{
  position:absolute;top:50%;font-size:17px;line-height:1;
  transform:translate(-50%,-50%);transition:left .8s ease;
  filter:drop-shadow(0 1px 3px rgba(0,0,0,.5));
}
.cdbar-note{
  margin-top:5px;font-size:11px;letter-spacing:2px;text-transform:uppercase;
  color:#a8c9b4;font-family:Georgia,serif;
}

/* --- stage 1: a long way off. plain green. --- */

/* --- stage 2: gold creeps in --- */
.cdbar[data-stage="2"] .cdbar-fill{
  background:linear-gradient(90deg,var(--green-light),var(--gold));
}
/* --- stage 3: candy-cane stripes --- */
.cdbar[data-stage="3"] .cdbar-fill{
  background:repeating-linear-gradient(115deg,
    var(--red) 0 9px, #fff 9px 18px);
}
/* --- stage 4: stripes, and a string of lights --- */
.cdbar[data-stage="4"] .cdbar-fill,
.cdbar[data-stage="5"] .cdbar-fill,
.cdbar[data-stage="6"] .cdbar-fill{
  background:repeating-linear-gradient(115deg,
    var(--red) 0 9px, #fff 9px 18px);
}
.cdbar[data-stage="4"] .cdbar-lights,
.cdbar[data-stage="5"] .cdbar-lights,
.cdbar[data-stage="6"] .cdbar-lights{
  opacity:1;
  background-image:
    radial-gradient(circle at 6px 50%, #ffe9a3 1.7px, transparent 2.4px),
    radial-gradient(circle at 18px 50%, #8ff2b8 1.7px, transparent 2.4px),
    radial-gradient(circle at 30px 50%, #ffb3bb 1.7px, transparent 2.4px);
  background-size:36px 100%;
}
/* --- stage 5: the lights start twinkling, snow settles on top --- */
.cdbar[data-stage="5"] .cdbar-lights,
.cdbar[data-stage="6"] .cdbar-lights{animation:twinkle 1.8s ease-in-out infinite}
.cdbar[data-stage="5"] .cdbar-snow,
.cdbar[data-stage="6"] .cdbar-snow{
  opacity:1;
  background:linear-gradient(180deg,rgba(255,255,255,.95) 0 3px,transparent 3px);
}
@keyframes twinkle{0%,100%{opacity:1}50%{opacity:.35}}

/* --- stage 6: nearly here. the whole thing glows. --- */
.cdbar[data-stage="6"] .cdbar-track{
  box-shadow:inset 0 1px 3px rgba(0,0,0,.35), 0 0 16px rgba(232,182,76,.55);
  border-color:rgba(246,217,138,.5);
}
.cdbar[data-stage="6"] .cdbar-head{animation:hop 1.1s ease-in-out infinite}
@keyframes hop{0%,100%{transform:translate(-50%,-50%)}50%{transform:translate(-50%,-72%)}}

/* --- the day itself --- */
.cdbar[data-stage="7"] .cdbar-fill{
  background:linear-gradient(90deg,var(--red),var(--gold),var(--green-light),var(--gold),var(--red));
  background-size:200% 100%;animation:shimmer 3.5s linear infinite;
}
@keyframes shimmer{0%{background-position:0 0}100%{background-position:200% 0}}
.cdbar[data-stage="7"] .cdbar-note{color:var(--gold-light)}

@media (prefers-reduced-motion:reduce){
  .cdbar-lights,.cdbar-head,.cdbar-fill{animation:none !important}
}
@media(max-width:640px){.cdbar{max-width:none}}
@media print{.cdbar{display:none !important}}

/* When there's a photo behind everything, the see-through menus need more
   backing or the text sits on whatever the picture happens to be doing. */
body.has-bg .menucard{background:rgba(5,33,20,.72);backdrop-filter:blur(6px)}
body.has-bg .breakfastcard{background:rgba(7,40,25,.72)}
body.has-bg .menucard::before{border-color:rgba(232,182,76,.65)}
body.has-bg .breakfastcard::before{border-color:rgba(143,214,172,.6)}

/* ---------- an item the owner has taken off their list ---------- */
.item.removed{opacity:.72;border-left-color:#b0a08e;background:#f7f2ea}
.item.removed .emoji{filter:grayscale(.55)}
.item.removed h4{text-decoration:line-through;text-decoration-color:#c4b49c;color:#7a6a5e}
.removed-note{
  margin-top:9px;font-size:14.5px;font-weight:700;color:#8a5b1f;
  background:#fdf0d6;border:1px dashed var(--gold-deep);border-radius:11px;padding:9px 12px;
}

/* ---------- alerts: something you claimed has been removed ---------- */
.alerts{margin-bottom:12px;display:grid;gap:10px}
.alert{
  display:flex;gap:13px;align-items:center;flex-wrap:wrap;
  background:#fff6e2;border:2px solid var(--gold);border-radius:14px;padding:13px 15px;
  box-shadow:0 3px 10px rgba(120,80,10,.12);
}
.alert-ic{font-size:30px;line-height:1;flex:0 0 auto}
.alert-body{flex:1;min-width:190px}
.alert-body strong{color:#8a5b1f;font-size:15.5px;display:block}
.alert-item{font-size:17px;font-weight:700;margin-top:2px;color:var(--ink)}
.alert-sub{font-size:14px;color:var(--muted);margin-top:2px}
.alert-acts{display:flex;gap:8px;flex-wrap:wrap}
.alert-btn{min-height:42px;padding:9px 16px;font-size:15px}
.alert .btn-ghost{color:var(--ink);border-color:#cdbfa5}

/* ---------- one window, two columns: what happened | what people said ---------- */
.split{display:grid;gap:0;grid-template-columns:1fr;min-height:0}
.split-col{display:flex;flex-direction:column;min-height:0;min-width:0}
.split .panel-title{font-size:17px;margin-bottom:10px}
@media(min-width:820px){
  .split{grid-template-columns:1.55fr 1fr;gap:20px}
  /* a hairline between them, so it reads as one window split in two */
  .split-col + .split-col{border-left:2px dashed #e3d5bf;padding-left:20px}
}
.stream.events .msg{display:none}
.stream.talk .ev{display:none}
.stream.talk .msg{padding:5px 2px}

/* ---------- the chat is the quieter half ---------- */
@media(min-width:820px){
  .split{grid-template-columns:1.75fr 1fr}
}
.split-col + .split-col .panel-title{color:#8a7768;font-size:15px;letter-spacing:.3px}
.stream.talk{max-height:min(52vh,520px)}
.stream.talk .msg .bub{font-size:15px;padding:8px 12px;background:#fdf9f0;border-color:#eee3d0}
.stream.talk .msg.mine .bub{background:#f1f7f2;border-color:#d6e7dc}
.stream.talk .msg .who{font-size:12px}
.stream.talk .msg .dot{width:28px;height:28px;font-size:12px}
.stream.talk .daysep{font-size:10px}
/* the message box shouldn't dominate either */
.chatbox textarea{min-height:52px;font-size:16px}
.chatrow .btn{min-height:44px;padding:11px 20px;font-size:16px}
.secretpick{font-size:14px}

/* the message box belongs to the chat column, not the whole window */
.split-col .chatbox{margin-top:10px;border-top:2px dashed #e9ddc8;padding-top:11px}
.split-col .chatbox textarea{min-height:48px;font-size:15.5px;padding:10px 12px}
.split-col .chatrow{gap:8px;margin-top:8px}
.split-col .chatrow .btn{min-height:42px;padding:10px 18px;font-size:15px}
.split-col .secretpick{font-size:13px;gap:5px}
.split-col .secretpick select{min-height:40px;font-size:14px;padding:6px 9px;border-radius:9px}
.split-col .secret-note{font-size:12px;margin-top:6px}
/* the activity column ends where its list ends */
.stream.events{max-height:min(60vh,620px)}

/* a message the author took back */
.msg.gone{opacity:.75}
.msg.gone .dot{filter:grayscale(.7)}
.gone-note{
  font-size:14px;font-style:italic;color:#9a8878;
  background:#f6f1e7;border:1px dashed #ded0b4;border-radius:12px;padding:7px 12px;
}



/* ---------- signed up, waiting to be let in ---------- */
.waitcard{text-align:center}
.waitbell{font-size:52px;line-height:1;animation:ring 3.4s ease-in-out infinite;transform-origin:top center}
@keyframes ring{
  0%,72%,100%{transform:rotate(0)}
  76%{transform:rotate(11deg)} 80%{transform:rotate(-9deg)}
  84%{transform:rotate(7deg)}  88%{transform:rotate(-5deg)} 92%{transform:rotate(2deg)}
}
.waitdots{display:flex;gap:9px;justify-content:center;margin:22px 0 4px}
.waitdots i{
  width:9px;height:9px;border-radius:50%;background:var(--gold-deep);opacity:.3;
  animation:waitdot 1.4s ease-in-out infinite;
}
.waitdots i:nth-child(2){animation-delay:.2s}
.waitdots i:nth-child(3){animation-delay:.4s}
@keyframes waitdot{0%,100%{opacity:.25;transform:translateY(0)}50%{opacity:1;transform:translateY(-4px)}}
.waitnote{font-size:14px;color:var(--muted);margin-top:14px;line-height:1.5}
@media (prefers-reduced-motion:reduce){
  .waitbell,.waitdots i{animation:none}
}

/* ---------- the organiser's "waiting to join" list ---------- */
.pending-title{
  margin:0 0 12px;font-size:15px;color:var(--green-dark);
  font-family:Georgia,"Times New Roman",serif;letter-spacing:.3px;
}
.pending-person{
  display:flex;align-items:center;gap:12px;padding:11px 13px;margin-bottom:9px;
  background:#fffaf0;border:1px solid #e6d3ac;border-radius:12px;
}
.pending-person .avatar{width:38px;height:38px;font-size:16px;flex:0 0 auto}
.pending-person .pp-who{flex:1 1 auto;min-width:0}
.pending-person .pp-name{font-weight:700;font-size:16px;color:var(--ink);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pending-person .pp-sub{font-size:12.5px;color:var(--muted)}
.pending-person .pp-acts{display:flex;gap:7px;flex:0 0 auto}
.pending-person button{
  border:0;border-radius:9px;padding:7px 12px;font-size:13.5px;font-weight:700;
  cursor:pointer;font-family:inherit;
}
.pending-person .pp-yes{background:var(--green);color:#fff}
.pending-person .pp-yes:hover{background:var(--green-dark)}
.pending-person .pp-no{background:transparent;color:var(--muted);border:1px solid #d8c8ab}
.pending-person .pp-no:hover{color:var(--red);border-color:var(--red)}
.pending-rule{border-top:1px dashed #d8c8ab;margin:16px 0 18px}
@media(max-width:520px){
  .pending-person{flex-wrap:wrap}
  .pending-person .pp-acts{width:100%;justify-content:flex-end}
}


/* =========================================================
   CHRISTMAS MORNING IS GOLD
   The supper card is the red-and-green one; the 25th gets gold leaf.
   Kept in one block at the end so it plainly beats the green rules
   further up and is easy to adjust in one place.
   ========================================================= */
.breakfastcard{background:rgba(42,28,6,.5)}
.breakfastcard::before{border-color:rgba(246,217,138,.62)}
.breakfastcard::after{border-color:rgba(246,217,138,.24)}
.breakfastcard .menucard-inner{border-color:rgba(232,182,76,.55)}

.breakfastcard .menu-orn{color:var(--gold)}
.breakfastcard .menu-head h3{
  color:var(--gold-light);
  /* a thin gold shimmer across the script, so it reads as leaf not paint */
  background:linear-gradient(100deg,#e8b64c 0%,#fbeab4 26%,#e8b64c 48%,#f6d98a 72%,#c9a227 100%);
  -webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;color:transparent;
  text-shadow:none;
}
.breakfastcard .menu-head::after{
  background:linear-gradient(90deg,transparent,var(--gold),transparent);height:2px;
}
.breakfastcard .menu-date{color:var(--gold-light)}
.breakfastcard .menu-sub{color:#d8c08a}

.breakfastcard .dish .nm{color:#fbeab4}
.breakfastcard .dish .dn{color:#cfb27a}
.breakfastcard .dish .who{color:#b09456}
.breakfastcard .dish + .dish{border-top-color:rgba(232,182,76,.24)}
.breakfastcard .menu-empty{color:#cfb27a}

.breakfastcard .menu-add{border-top-color:rgba(232,182,76,.45)}
.breakfastcard .menu-add-title{color:#d8c08a}
.breakfastcard .food-opt.sel{
  border-color:var(--gold-deep);background:#fff6e0;
  box-shadow:0 0 0 2px rgba(185,134,42,.25);
}
.breakfastcard .viewfull{color:var(--gold)}
.breakfastcard .viewfull:hover{background:rgba(232,182,76,.16);color:var(--gold-light)}

/* on a photo backdrop the card goes darker so the gold keeps its contrast */
body.has-bg .breakfastcard{background:rgba(32,21,4,.76)}
body.has-bg .breakfastcard::before{border-color:rgba(246,217,138,.7)}

/* printed, it is ink on white — gradients and pale gold vanish on paper */
@media print{
  .breakfastcard .menu-head h3{
    -webkit-text-fill-color:#a8811b !important;color:#a8811b !important;
    background:none !important;
  }
  .breakfastcard .menu-date,.breakfastcard .menu-sub{color:#a8811b !important}
  .breakfastcard .dish .nm{color:#2b1d18 !important}
  .breakfastcard .dish .dn,.breakfastcard .dish .who{color:#6f5b52 !important}
}

/* =========================================================
   THE TWO VIEWS — what's happening, and everyone's lists
   The tabs sit in the header between the title and the player. They are
   deliberately trim: the header also carries the countdown, the player and
   two buttons, and at 1560px wide there is only so much room before the
   whole lot wraps onto another line.
   ========================================================= */
.tabs{display:flex;gap:4px;flex-wrap:wrap;flex:0 0 auto}
.tab{gap:5px}
.tab{
  display:inline-flex;align-items:center;gap:6px;cursor:pointer;
  font:inherit;font-size:13px;font-weight:700;color:#cfe6d6;
  background:rgba(255,255,255,.07);border:1px solid rgba(255,255,255,.13);
  border-radius:999px;padding:9px 11px;min-height:40px;
  transition:background .14s,color .14s,border-color .14s;
  -webkit-tap-highlight-color:transparent;white-space:nowrap;
}
.tab:hover{background:rgba(255,255,255,.14);color:#fff}
.tab.on{
  background:var(--gold);border-color:var(--gold-light);color:#3a2a08;
  box-shadow:0 2px 10px rgba(0,0,0,.3);
}
.tab:focus-visible{outline:2px solid var(--gold-light);outline-offset:2px}
.tab-ic{font-size:15px;line-height:1}

/* ---------- the board: one column per person ---------- */
.boardpanel{
  padding:18px 0 16px;
  /* fill what's left of the window under the header and tabs */
  min-height:calc(100vh - 300px);
}
.board{align-items:stretch}
.board-head{
  display:flex;align-items:baseline;gap:12px;flex-wrap:wrap;
  padding:0 20px;margin-bottom:12px;
}
.board-head .panel-title{margin:0}
.board-hint{font-size:12.5px;color:var(--muted);font-style:italic}

.board{
  display:flex;gap:14px;align-items:flex-start;
  overflow-x:auto;overflow-y:hidden;
  padding:2px 20px 12px;
  scroll-snap-type:x proximity;
  scrollbar-width:thin;
}
.board::-webkit-scrollbar{height:9px}
.board::-webkit-scrollbar-thumb{background:#d9c8a8;border-radius:9px}
.board::-webkit-scrollbar-track{background:transparent}

.bcol{
  flex:0 0 236px;width:236px;scroll-snap-align:start;
  background:#fffaf0;border:1px solid #e7d8ba;border-radius:16px;
  display:flex;flex-direction:column;
  /* as tall as the window allows — the columns are the whole point of this
     view, so they get the room rather than stopping two thirds down */
  height:100%;
}
.bcol.mine{border-color:var(--gold);background:#fffdf6;box-shadow:0 0 0 2px rgba(232,182,76,.22)}

.bcol-head{
  display:flex;align-items:center;gap:9px;padding:12px 13px 10px;
  border-bottom:1px dashed #e0cfae;cursor:pointer;flex:0 0 auto;
}
.bcol-head:hover .bcol-name{text-decoration:underline}
.bcol-head .avatar{width:34px;height:34px;font-size:15px;flex:0 0 auto}
.bcol-who{min-width:0;flex:1 1 auto}
.bcol-name{
  font-weight:800;font-size:15.5px;color:var(--ink);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.bcol-count{font-size:12px;color:var(--muted)}
.bcol-mine-tag{
  font-size:9.5px;font-weight:800;letter-spacing:.8px;text-transform:uppercase;
  background:var(--gold);color:#3a2a08;border-radius:99px;padding:2px 7px;flex:0 0 auto;
}

.bcol-items{overflow-y:auto;padding:9px;display:flex;flex-direction:column;gap:8px;flex:1 1 auto}
.bcol-empty{
  padding:20px 12px;text-align:center;color:var(--muted);
  font-size:13.5px;font-style:italic;line-height:1.5;
}

.bitem{
  background:#fff;border:1px solid #eadfc8;border-left:3px solid #e0cfae;
  border-radius:11px;padding:9px 10px;font-size:14px;
}
.bitem.claimed{border-left-color:var(--gold-deep);background:#fffaec}
.bitem.removed{opacity:.55;background:#f4efe4}
.bitem-top{display:flex;gap:8px;align-items:flex-start}
.bitem-em{font-size:19px;line-height:1.2;flex:0 0 auto}
.bitem-title{
  font-weight:700;color:var(--ink);line-height:1.3;min-width:0;
  overflow-wrap:anywhere;
}
.bitem.removed .bitem-title{text-decoration:line-through}
.bitem-note{font-size:12.5px;color:var(--muted);margin-top:3px;line-height:1.4;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.bitem-row{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin-top:7px}
.bitem-price{
  font-size:11.5px;font-weight:700;color:var(--green-dark);
  background:#e9f5ec;border-radius:99px;padding:2px 8px;
}
.bitem-link{
  font-size:11.5px;color:var(--muted);text-decoration:none;
  background:#f2ece0;border-radius:99px;padding:2px 8px;max-width:100%;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.bitem-link:hover{color:var(--red);background:#fdf1d9}
.bitem-tag{
  font-size:11px;font-weight:700;border-radius:99px;padding:2px 8px;
  background:#fdf1d9;color:var(--gold-deep);
}
.bitem-tag.gone{background:#efe6d6;color:var(--muted)}
.bitem-btn{
  font:inherit;font-size:12px;font-weight:700;cursor:pointer;
  border:0;border-radius:8px;padding:5px 11px;min-height:30px;
  background:var(--gold);color:#3a2a08;
}
.bitem-btn:hover{background:var(--gold-light)}
.bitem-btn.undo{background:transparent;color:var(--muted);border:1px solid #d8c8ab}
.bitem-btn.undo:hover{color:var(--red);border-color:var(--red)}
.bitem-btn[disabled]{opacity:.5;pointer-events:none}

.bcol-add{
  flex:0 0 auto;padding:9px;border-top:1px dashed #e0cfae;
}
.bcol-add button{
  width:100%;font:inherit;font-size:13px;font-weight:700;cursor:pointer;
  background:transparent;border:1.5px dashed #d8c8ab;border-radius:10px;
  padding:9px;color:var(--muted);min-height:38px;
}
.bcol-add button:hover{border-color:var(--green);color:var(--green-dark);background:#f2f9f4}

/* your own column says nothing about claims, and says so out loud */
.bcol-secret{
  font-size:11.5px;color:var(--gold-deep);background:#fff6e0;
  padding:7px 10px;margin:0;border-bottom:1px dashed #e8d9b8;
  line-height:1.4;flex:0 0 auto;
}

@media(max-width:700px){
  /* on a phone they get a line of their own, split evenly */
  .tabs{order:3;width:100%;gap:6px}
  .tab{flex:1 1 0;justify-content:center;padding:9px 8px;font-size:12.5px}
  .board{padding:2px 12px 12px;gap:11px}
  .bcol{flex-basis:210px;width:210px}
  .board-head{padding:0 14px}
}

/* The header carries a lot now — title, countdown, tabs, player, two
   buttons. Grouping the right-hand controls means that when it does run
   out of room they drop to the next line together and stay right-aligned,
   instead of Sign out wandering off on its own. */
.topright{
  display:flex;align-items:center;gap:12px;margin-left:auto;
  flex-wrap:wrap;justify-content:flex-end;
}
@media(max-width:1500px){
  .player .pmid{width:132px}
}
@media(max-width:1180px){
  .player .pbar,.player .ptime{display:none}
  .player .pmid{width:104px}
}
@media(max-width:700px){
  .topright{width:100%;justify-content:center;order:4}
}

/* a soft fade on the right of the board, so it looks like it carries on */
.boardpanel{position:relative}
.boardpanel::after{
  content:"";position:absolute;top:52px;right:0;bottom:16px;width:34px;
  pointer-events:none;border-radius:0 16px 16px 0;
  background:linear-gradient(90deg,rgba(253,246,233,0),var(--card));
}

/* ---------- "these are ideas, not a shopping list" ---------- */
.board-note{font-size:12.5px;color:var(--gold-deep);font-weight:600}
.owner-banner .kindline{
  display:block;margin-top:7px;font-size:13.5px;color:var(--gold-deep);font-weight:600;
}
.kindsheet{max-width:430px;text-align:center;border-radius:24px}
.kind-heart{
  font-size:52px;line-height:1;margin-bottom:6px;
  animation:beat 2.6s ease-in-out infinite;
}
@keyframes beat{
  0%,100%{transform:scale(1)} 8%{transform:scale(1.14)} 16%{transform:scale(1)}
  24%{transform:scale(1.09)} 34%{transform:scale(1)}
}
@media (prefers-reduced-motion:reduce){.kind-heart{animation:none}}
.kindsheet h3{text-align:center;margin-bottom:12px}
.kind-body{
  margin:0 0 12px;color:var(--muted);font-size:15px;line-height:1.6;
}
.kind-body strong{color:var(--green-dark)}

/* ---------- station + volume, tucked behind the ⋯ on the player ---------- */
.player{position:relative}
.pmore{width:28px;height:28px;font-size:15px;opacity:.72;letter-spacing:1px}
.pmore:hover{opacity:1}
.player.panelopen .pmore{opacity:1;background:rgba(255,255,255,.16)}

.ppanel{
  position:absolute;top:calc(100% + 9px);right:0;z-index:60;
  width:238px;padding:13px 14px;border-radius:15px;
  background:var(--cream);box-shadow:0 12px 34px rgba(0,0,0,.4);
  border:1px solid #e3d5bf;
}
.ppanel::before{
  content:"";position:absolute;top:-7px;right:16px;width:12px;height:12px;
  background:var(--cream);border-left:1px solid #e3d5bf;border-top:1px solid #e3d5bf;
  transform:rotate(45deg);
}
.pp-row + .pp-row{margin-top:13px;padding-top:13px;border-top:1px dashed #e0cfae}
.pp-label{
  font-size:10px;letter-spacing:2.2px;text-transform:uppercase;
  color:var(--muted);font-family:Georgia,serif;margin-bottom:8px;
}
.pp-stations{display:flex;gap:6px;flex-wrap:wrap}
.pp-station{
  font:inherit;font-size:13px;font-weight:700;cursor:pointer;
  background:#fff;border:2px solid #e3d5bf;border-radius:99px;
  padding:6px 13px;color:var(--muted);min-height:34px;
  transition:border-color .12s,background .12s,color .12s;
}
.pp-station:hover{border-color:var(--green-light);color:var(--green-dark)}
.pp-station.on{background:var(--green);border-color:var(--green);color:#fff}
.pp-station .n{opacity:.65;font-weight:600;font-size:11.5px;margin-left:4px}

.pp-vol{display:flex;align-items:center;gap:9px}
.pp-mute{
  background:none;border:0;cursor:pointer;font-size:17px;line-height:1;
  padding:2px;border-radius:6px;flex:0 0 auto;
}
.pp-mute:hover{background:#f2ece0}
.pp-vol input[type=range]{
  flex:1 1 auto;min-width:0;height:4px;-webkit-appearance:none;appearance:none;
  background:linear-gradient(90deg,var(--gold-deep) 0 var(--pct,45%),#e3d5bf var(--pct,45%) 100%);
  border-radius:3px;cursor:pointer;
}
.pp-vol input[type=range]::-webkit-slider-thumb{
  -webkit-appearance:none;width:15px;height:15px;border-radius:50%;
  background:#fff;border:2px solid var(--gold-deep);cursor:pointer;
}
.pp-vol input[type=range]::-moz-range-thumb{
  width:15px;height:15px;border-radius:50%;background:#fff;
  border:2px solid var(--gold-deep);cursor:pointer;
}
.pp-volnum{
  font-size:11.5px;color:var(--muted);font-variant-numeric:tabular-nums;
  min-width:20px;text-align:right;flex:0 0 auto;
}

/* ---------- suggestions, out of the way ----------
   It used to be a full button in the header, which is a lot of shouting for
   a suggestion box. Now it lives quietly in the footer, and the header only
   shows a small marker when the organiser actually has something waiting. */
.topalert{
  padding:7px 10px;min-height:34px;text-decoration:none;font-size:16px;
  background:rgba(179,32,44,.9);border-radius:99px;
}
.topalert:hover{background:var(--red);color:#fff}
.topalert .sugg-count{margin-left:5px;background:#fff;color:var(--red)}

footer{display:flex;align-items:center;justify-content:center;gap:9px;flex-wrap:wrap}
.footdot{opacity:.4}
.footlink{
  background:none;border:0;font:inherit;font-size:inherit;cursor:pointer;
  color:inherit;opacity:.62;text-decoration:underline;
  text-underline-offset:3px;text-decoration-color:rgba(255,255,255,.25);
  padding:4px 6px;border-radius:7px;
}
.footlink:hover{opacity:1;text-decoration-color:currentColor}

/* ---------- the stations, out on the bar where you can see them ----------
   They were behind the ⋯ to save room, but a station you have to go
   looking for isn't really a choice. Now they sit on the player itself and
   the ⋯ became a plain volume button. */
.pstations{display:flex;gap:3px;flex:0 0 auto;background:rgba(0,0,0,.22);
  border-radius:999px;padding:3px}
.pstations:empty{display:none}
.pstation{
  font:inherit;font-size:12px;font-weight:700;cursor:pointer;white-space:nowrap;
  background:transparent;border:0;border-radius:999px;padding:5px 11px;
  color:#a9c7b6;min-height:26px;line-height:1;
  transition:background .14s,color .14s;-webkit-tap-highlight-color:transparent;
}
.pstation:hover{color:#fff;background:rgba(255,255,255,.1)}
.pstation.on{background:var(--gold);color:#3a2a08}
.pstation:focus-visible{outline:2px solid var(--gold-light);outline-offset:2px}

/* the panel now holds only the volume, so it can be narrower */
.ppanel{width:210px}
.ppanel .pp-row + .pp-row{margin-top:13px}

@media(max-width:1500px){
  .pstation{padding:5px 9px;font-size:11.5px}
}
@media(max-width:700px){
  /* on a phone the seek bar and time are already gone, so these still fit */
  .pstations{padding:2px}
  .pstation{padding:5px 8px;font-size:11px}
}

/* The lists view is a board, so it wants the height. The panel stretches to
   the bottom of the window and the columns stretch with it, each scrolling
   its own gifts rather than everything stopping short two thirds down. */
/* :not([hidden]) matters — a plain "#viewLists{display:flex}" beats the
   browser's own rule for the hidden attribute, so the board carried on
   rendering underneath the chat when it was supposed to be put away. */
/* Wrapping the panel and the family grid in #viewHome took away the 18px
   the flex gap used to put between them, so they sat welded together. */
#viewHome:not([hidden]){display:flex;flex-direction:column;gap:18px}
/* flex:1 makes the board fill its column. Without it the panel stopped at
   whatever the tallest gift column happened to need and left the menus
   beside it running on for another two screens — the lists tab looked like
   it had been cut off halfway. */
#viewLists:not([hidden]){display:flex;flex-direction:column;min-height:0;flex:1 1 auto}
#viewLists .boardpanel{flex:1 1 auto;display:flex;flex-direction:column;min-height:0}
#viewLists .board{flex:1 1 auto;min-height:0;align-items:stretch}
#viewLists .bcol{max-height:none}
#viewLists .bcol-items{min-height:0}

/* on the lists tab the family grid underneath isn't needed — the board is
   the family grid — so the column can use the whole height */
@media(min-width:1000px){
  .home-grid:has(#viewLists:not([hidden])){align-items:stretch}
  /* Come down as far as the menus beside it, but never further than a
     screenful and a bit — stretched to the full height of a long menu the
     board turned into an acre of empty cream. */
  #viewLists:not([hidden]){max-height:calc(100vh - 96px)}
  #viewLists .boardpanel{min-height:calc(100vh - 190px)}
}
@media(max-width:999px){
  #viewLists .boardpanel{min-height:auto}
  #viewLists .bcol{height:auto;max-height:70vh}
}

/* The sign-in and doorstep screens: background and card, nothing else.
   The header is hidden rather than emptied, so nothing is left holding
   space, and the card sits a little way down from the top instead. */
body.bare header.top{display:none}
body.bare .wrap{padding-top:6vh}
@media(max-height:700px){body.bare .wrap{padding-top:24px}}

/* Belt and braces for the whole page: if something is marked hidden, it is
   hidden, whatever else the stylesheet says about it. */
[hidden]{display:none !important}

/* Fitting the header on one line.

   It carries the title, the countdown, two tabs, the player and two
   buttons — about 1580px of things. The page content is capped at 1560,
   and once the header hit that cap the whole right-hand group dropped to a
   second line and the header grew from 156px tall to 226px.

   So on a screen with the room to spare, the header alone is allowed to
   run wider than the content beneath it. It reads as deliberate, and it
   buys the 140px that keeps everything on one line. Narrower screens wrap,
   which is fine — that is what wrapping is for. */
@media(min-width:1000px){
  .player .pmid{width:150px}
  .topright{gap:10px}
}
@media(min-width:1600px){ header.top{max-width:1700px} }
@media(min-width:1800px){ header.top{max-width:1790px} }

/* ---------- the tabs sit ON the card ----------
   Only once the header is a single row, because that is the only time the
   tabs are the thing directly above the card. Below 1600px the header
   wraps, the player ends up between them, and they go back to being plain
   pills floating on the green.

   align-self:flex-end drops them to the bottom of the header row, which
   leaves exactly the header's own 20px of bottom padding between them and
   the card. -21px closes that and laps one pixel over the card's edge, so
   the tab you're on runs into it with no green showing between. */
@media(min-width:1600px){
  .tabs{align-self:flex-end;margin-bottom:-21px;position:relative;z-index:5;gap:5px}
  .tab{
    background:#f0e4cd;color:#8a7358;
    border:1px solid #e0cfae;border-bottom:none;
    border-radius:14px 14px 0 0;
    padding:10px 16px 11px;min-height:auto;
    box-shadow:0 -3px 10px rgba(0,0,0,.16);
    position:relative;top:3px;
  }
  .tab:hover{background:#f6ecda;color:var(--ink)}
  .tab.on{
    background:var(--card);color:var(--green-dark);
    border-color:#e6d6b6;
    top:0;padding-bottom:14px;          /* laps over the card so they merge */
    box-shadow:0 -4px 14px rgba(0,0,0,.2);
  }
  .tab:focus-visible{outline:2px solid var(--gold-deep);outline-offset:-3px}
}

/* =========================================================
   PHONES
   The header had grown to carry a title, a countdown, two tabs, a whole
   music player and two buttons. On a 375px screen that ran the player off
   the edge and left every control at about half the size of a fingertip.
   Below 700px it all gets laid out properly instead of squeezed.
   ========================================================= */
@media(max-width:700px){
  header.top{padding:14px 13px 12px;gap:10px}
  .brand{gap:10px}
  .brand .tree{font-size:30px}
  .cdbar{margin-top:7px}
  .cdbar-note{font-size:10px;letter-spacing:1.4px}

  /* the player gets two lines of its own rather than one cramped one:
     the controls, then the stations underneath, both full width */
  .topright{width:100%;gap:8px}
  .player{
    width:100%;flex-wrap:wrap;gap:7px;padding:8px 10px;border-radius:20px;
  }
  /* 44px is about a fingertip — everything you tap gets at least that */
  .pbtn-play{width:44px;height:44px;font-size:20px}
  .pskip{width:44px;height:44px;font-size:15px;opacity:.85}
  .pmore{width:44px;height:44px;font-size:17px}
  .pmid{flex:1 1 60px;width:auto;min-width:0}
  .ptrack{font-size:12.5px}
  .pbar,.ptime{display:none}

  .pstations{order:9;flex:1 1 100%;justify-content:stretch;padding:3px;gap:4px}
  .pstation{
    flex:1 1 0;display:inline-flex;align-items:center;justify-content:center;
    min-height:40px;font-size:13px;padding:8px 10px;
  }

  /* the two buttons at the end share a line */
  #openSugg{min-height:44px;padding:9px 13px}
  #signout{min-height:44px}

  /* the panel drops from the volume button, so keep it on screen */
  .ppanel{right:0;left:auto;width:min(240px,calc(100vw - 40px))}

  /* one person's column at a time, and it snaps as you swipe */
  .board{scroll-snap-type:x mandatory;padding:2px 14px 12px}
  .bcol{flex-basis:min(78vw,300px);width:min(78vw,300px);scroll-snap-align:center}

  /* the sign-in page's "create an account" link was an 18px-tall target */
  #switchLink{display:inline-block;padding:10px 8px;min-height:40px}
}

/* Anything under about 44px square is a coin toss with a thumb, and a lot
   of these were nearer 20px.

   Keyed on the POINTER, not the screen width. An iPad is a touch screen at
   834px and up, so a width rule left every control on it mouse-sized —
   which is exactly the device Mark's mum uses. "pointer: coarse" catches
   every finger-driven screen, phone or tablet, and leaves a desktop with a
   mouse alone. */
@media (pointer: coarse){
  .pbtn-play{width:44px;height:44px;font-size:20px}
  .pskip{width:44px;height:44px;font-size:15px;opacity:.85}
  .pmore{width:44px;height:44px;font-size:17px}
  .pstation{
    display:inline-flex;align-items:center;justify-content:center;
    min-height:40px;font-size:13px;padding:8px 13px;
  }
  /* the scrub line stays thin to look at but gets a fat invisible grab area */
  .pbar{padding:14px 0}

  .msg .rm{width:40px;min-width:40px;height:40px;padding:0;display:grid;place-items:center;font-size:15px}
  .dish .x{width:40px;height:40px;display:grid;place-items:center;font-size:16px;top:0;right:-4px}
  .food-opt{min-height:44px;font-size:20px}
  .emoji-opt{min-height:58px}
  .viewfull{min-height:46px;padding:13px 9px}
  .footlink{min-height:44px;padding:11px 10px;display:inline-flex;align-items:center}
  .bcol-add button{min-height:44px}
  .bitem-btn{min-height:42px;padding:10px 14px;font-size:13px}
  .bitem-link{min-height:40px;display:inline-flex;align-items:center;padding:9px 11px}
  .item .del{min-height:44px}
  .claimbtn{min-height:44px}
  .alert-btn{min-height:44px}
  .sugg-item .acts button{min-height:40px}
  .pending-person button{min-height:42px}
  #openSugg{min-height:44px;padding:9px 13px}
  #signout{min-height:44px}
  #switchLink{display:inline-block;padding:10px 8px;min-height:40px}
  .tab{min-height:44px}
}

/* Phone-shaped screens also need the layout rearranged, not just bigger
   buttons — see the block above this one for that. */
@media(max-width:700px){
  /* the header is over half a small screen before any content shows, so the
     decorative half of the countdown steps aside — the numbers stay */
  header.top{gap:8px}
  .cdbar-note{display:none}
  .brand h1{font-size:clamp(19px,5.2vw,24px)}
  .countdown{font-size:12px}
}

/* the short tab labels only show on a phone, where three full ones won't fit */
.tab-sh{display:none}
#viewMine .board-head{padding:0;margin-bottom:12px}
#viewMine .items{display:flex;flex-direction:column;gap:12px}
#viewMine .addbar{margin-top:14px}
/* The Add-a-gift bar fades out of the page behind it so the list looks like
   it carries on underneath. On the list page that page is dark green; on the
   My list tab it is the cream of the panel, and the green version showed up
   as a slab sitting behind the button. */
#viewMine .addbar{background:linear-gradient(180deg,rgba(255,250,241,0),var(--card) 45%)}
@media(max-width:700px){
  .tab-tx{display:none}
  .tab-sh{display:inline}
  .tab{padding:9px 6px;font-size:12.5px;gap:5px}
}

/* ---------- pets ----------
   A pet sits in the family list like anybody else, with a paw badge and
   either a photo or their animal icon in place of an initial. */
.addpet{
  margin-top:14px;width:100%;font:inherit;font-size:14px;font-weight:700;
  background:transparent;border:1.5px dashed #d8c8ab;border-radius:12px;
  padding:11px;color:var(--muted);cursor:pointer;min-height:44px;
}
.addpet:hover{border-color:var(--green);color:var(--green-dark);background:#f2f9f4}

.person.pet .avatar,.bcol.pet .avatar{background:#6b4f2a}
.avatar.hasphoto{background-size:cover;background-position:center;color:transparent}
.person .petbadge{
  display:inline-block;font-size:10px;font-weight:800;letter-spacing:.7px;
  text-transform:uppercase;background:#efe3cd;color:#7a6440;
  border-radius:99px;padding:2px 8px;margin-top:5px;
}
.bcol-pettag{
  font-size:9.5px;font-weight:800;letter-spacing:.8px;text-transform:uppercase;
  background:#efe3cd;color:#7a6440;border-radius:99px;padding:2px 7px;flex:0 0 auto;
}
.petgrid{max-height:170px}
.removepet{
  background:none;border:0;font:inherit;font-size:13px;color:var(--muted);
  cursor:pointer;text-decoration:underline;text-underline-offset:3px;
  padding:8px 6px;min-height:40px;
}
.removepet:hover{color:var(--red)}

/* =========================================================
   EVERYONE'S LISTS — the main thing, so it sits at the top
   and looks like it matters.
   ========================================================= */
.peoplebox{
  position:relative;overflow:hidden;
  background:
    /* a soft warm glow in the top corners, like light off a tree */
    radial-gradient(120% 90% at 8% -20%, rgba(232,182,76,.20), transparent 60%),
    radial-gradient(120% 90% at 92% -20%, rgba(179,32,44,.14), transparent 60%),
    var(--card);
  border:1px solid #e6d6b6;
  box-shadow:0 10px 30px rgba(60,20,20,.16);
}
/* (the striped garland that used to run across the top lives on the wooden
   frame's holly now — three decorations stacked was one too many) */
.peoplebox .panel-title{
  margin-top:6px;font-size:22px;
  display:flex;align-items:center;gap:9px;
  border-bottom:2px dashed #e3d5bf;
}
/* a sprig either side of the heading */
.peoplebox .panel-title::after{
  content:"❄";margin-left:auto;color:var(--gold-deep);font-size:17px;opacity:.75;
}

.peoplebox .person{
  position:relative;
  background:linear-gradient(180deg,#fffdf7,#fdf4e4);
  border:1px solid #e8d9bb;
  transition:transform .12s,box-shadow .12s,border-color .12s;
}
.peoplebox .person:hover{
  transform:translateY(-3px);
  border-color:var(--gold);
  box-shadow:0 8px 20px rgba(60,20,20,.16);
}
/* a little gold ribbon on the card you own */
.peoplebox .person .me{
  background:var(--gold);color:#3a2a08;font-weight:800;
}
.peoplebox .person::after{
  content:"";position:absolute;inset:auto 0 0 0;height:3px;
  background:linear-gradient(90deg,transparent,var(--gold),transparent);
  opacity:0;transition:opacity .12s;
}
.peoplebox .person:hover::after{opacity:1}

/* ---------- the garland between the lists and the chat ---------- */
/* Pulled up so its pins and bows land on the bottom edge of the wooden
   frame above — the garland is strung from the timber rather than floating
   in the gap between the two panels. */
.mantel{margin:-34px 0 -14px;pointer-events:none;line-height:0;position:relative;z-index:4}
.mantel svg{width:100%;height:auto;display:block;overflow:visible;
  filter:drop-shadow(0 4px 7px rgba(0,0,0,.35))}
/* the hanging baubles swing, each on its own timing */
.mantel-hang{transform-box:fill-box;transform-origin:top center;
  animation:mantelsway 5.2s ease-in-out infinite}
@keyframes mantelsway{0%,100%{transform:rotate(-3deg)}50%{transform:rotate(3deg)}}
@media (prefers-reduced-motion:reduce){.mantel-hang{animation:none}}
@media(max-width:700px){.mantel{margin:-22px 0 -12px}}

/* ---------- Everyone's lists gets more room ----------
   It is the main thing on the page, so it should look like it rather than
   being a thin strip above the chat. */
.peoplebox{padding:18px 18px 22px}
.peoplebox .panel-title{margin-bottom:18px}
.peoplebox .family{grid-template-columns:repeat(auto-fill,minmax(158px,1fr));gap:15px}
.peoplebox .person{padding:22px 12px 18px;border-width:2px}
.peoplebox .avatar{width:70px;height:70px;font-size:30px;margin-bottom:11px}
.peoplebox .person h3{font-size:17.5px}
.peoplebox .person .count{font-size:13.5px;margin-top:4px}
.peoplebox .person .me{font-size:10px;padding:3px 9px;margin-top:8px}
.peoplebox .petbadge{margin-top:7px}
@media(min-width:1240px){
  .peoplebox .family{grid-template-columns:repeat(auto-fill,minmax(172px,1fr))}
  .peoplebox .avatar{width:78px;height:78px;font-size:33px}
  .peoplebox .person{padding:26px 12px 20px}
  .peoplebox .person h3{font-size:19px}
}

/* =========================================================
   THE WOOD FRAME
   Four boards mitred at the corners, dark mahogany, weathered.

   The detail that sells it is grain direction: the top and bottom boards
   run left-to-right so their grain lines are horizontal, the two side
   boards run up-and-down so theirs are vertical. One grain over the whole
   thing reads as printed paper; grain that turns at the corners reads as
   four lengths of timber.
   ========================================================= */
.woodframe{
  position:relative;
  --plank: 30px;
  padding:var(--plank);
  border-radius:10px;
  /* the fallback, until the generated timber arrives a frame later */
  background:linear-gradient(174deg,#3f1d11,#2c1209 55%,#1d0b05);
  box-shadow:
    inset 0 3px 0 rgba(226,170,128,.22),      /* light along the top edge */
    inset 0 -4px 0 rgba(0,0,0,.5),            /* shadow under the bottom */
    inset 5px 0 10px rgba(0,0,0,.26),
    inset -5px 0 10px rgba(0,0,0,.26),
    0 18px 40px rgba(18,5,1,.55);
}
/* Four boards, each showing the timber with its grain running the right
   way: along the top and bottom rails, down the two sides. The images are
   generated in app.js and tile, so a frame of any size is just the board
   repeated. */
.haswood .woodframe{
  background:
    var(--wood-h) top left / auto var(--plank) repeat-x,
    var(--wood-h) bottom left / auto var(--plank) repeat-x,
    var(--wood-v) top left / var(--plank) auto repeat-y,
    var(--wood-v) top right / var(--plank) auto repeat-y,
    #2c1209;
}

/* the mitres, where the four boards meet */
.woodframe::before{
  content:"";position:absolute;inset:0;border-radius:10px;pointer-events:none;
  background:
    linear-gradient(45deg,  transparent 49.2%, rgba(16,5,1,.6) 49.2% 50.8%, rgba(214,158,116,.10) 50.8% 51.6%, transparent 51.6%)
      top left / var(--plank) var(--plank) no-repeat,
    linear-gradient(135deg, transparent 49.2%, rgba(16,5,1,.6) 49.2% 50.8%, rgba(214,158,116,.10) 50.8% 51.6%, transparent 51.6%)
      top right / var(--plank) var(--plank) no-repeat,
    linear-gradient(135deg, transparent 48.4%, rgba(214,158,116,.10) 48.4% 49.2%, rgba(16,5,1,.6) 49.2% 50.8%, transparent 50.8%)
      bottom left / var(--plank) var(--plank) no-repeat,
    linear-gradient(45deg,  transparent 48.4%, rgba(214,158,116,.10) 48.4% 49.2%, rgba(16,5,1,.6) 49.2% 50.8%, transparent 50.8%)
      bottom right / var(--plank) var(--plank) no-repeat;
}
/* the rebate where the boards meet the card */
.woodframe::after{
  content:"";position:absolute;inset:calc(var(--plank) - 7px);border-radius:8px;pointer-events:none;
  box-shadow:
    0 0 0 1px rgba(226,170,128,.13),
    inset 0 0 0 1px rgba(16,5,1,.7),
    inset 0 5px 11px rgba(16,5,1,.5);
}
.woodframe > .peoplebox,
.woodframe > .panel{box-shadow:none;border-radius:6px}

/* holly sprigs pinned to the frame, drawn in app.js */
.holly{position:absolute;width:146px;height:110px;pointer-events:none;z-index:3;
  filter:drop-shadow(0 4px 6px rgba(0,0,0,.5))}
.holly svg,.holly img{width:100%;height:100%;display:block;overflow:visible}
.holly.tl{top:-26px;left:-22px}
.holly.tr{top:-26px;right:-22px;transform:scaleX(-1)}
.holly.bl{bottom:-26px;left:-22px;transform:scaleY(-1)}
.holly.br{bottom:-26px;right:-22px;transform:rotate(180deg)}
/* smaller sprigs halfway along each rail */
.holly.tc{top:-19px;left:50%;width:104px;height:78px;transform:translateX(-58%)}
.holly.bc{bottom:-19px;left:50%;width:104px;height:78px;transform:translateX(-42%) rotate(180deg)}
.holly.lc{top:50%;left:-18px;width:92px;height:70px;transform:translateY(-56%) rotate(90deg)}
.holly.rc{top:50%;right:-18px;width:92px;height:70px;transform:translateY(-44%) rotate(-90deg) scaleY(-1)}

@media(max-width:700px){
  .woodframe{--plank:17px;border-radius:8px}
  .woodframe::before{border-radius:8px}
  .woodframe > .peoplebox,.woodframe > .panel{border-radius:5px}
  .holly{width:88px;height:66px}
  .holly.tl{top:-15px;left:-12px}
  .holly.tr{top:-15px;right:-12px}
  .holly.bl{bottom:-15px;left:-12px}
  .holly.br{bottom:-15px;right:-12px}
  /* the mid-rail sprigs are too much on a narrow screen */
  .holly.tc,.holly.bc,.holly.lc,.holly.rc{display:none}
}

/* Once the tabs reach down to the panel they now land on the wooden frame
   rather than the cream card, so the one you are on takes the timber
   colouring and looks slotted into it. */
@media(min-width:1600px){
  .tab{background:#261008;border-color:#180a04;color:#d8b295}
  .tab:hover{background:#3a1a0e;color:#fff}
  .tab.on{
    background:linear-gradient(176deg,#54291a,#3f1d11 60%,#341709);
    border-color:#180a04;color:#f6e2d0;
    box-shadow:0 -4px 14px rgba(0,0,0,.45), inset 0 2px 0 rgba(214,158,116,.24);
  }
}

/* The other two tabs get the same frame. The board still has to stretch to
   the bottom of the window, so the frame becomes the flexing item and the
   panel flexes inside it. */
#viewLists > .woodframe{
  flex:1 1 auto;display:flex;flex-direction:column;min-height:0;
}
#viewLists > .woodframe > .boardpanel{flex:1 1 auto;min-height:0}
#viewMine > .woodframe > .panel{min-height:0}
/* the fade at the right edge of the board sits inside the frame now */
.boardpanel::after{border-radius:0 6px 6px 0}

/* the fairy lights in the garland, each blinking on its own clock */
.twinkle{animation:twinkle 2.8s ease-in-out infinite}
@keyframes twinkle{
  0%,100%{opacity:.32}
  45%{opacity:1}
  60%{opacity:.75}
}
@media (prefers-reduced-motion:reduce){.twinkle{animation:none;opacity:.85}}

/* ---------- the tree beside a list ----------
   One decoration for every gift. Bare to begin with, so a new list looks
   like something waiting to be filled rather than something empty. */
.listgrid{display:grid;gap:20px;grid-template-columns:1fr}
@media(min-width:900px){
  .listgrid{grid-template-columns:minmax(0,1fr) 320px;align-items:start}
}
.listmain{min-width:0}
.treeside{min-width:0}
.treebox{
  background:
    radial-gradient(120% 70% at 50% 0%, rgba(232,182,76,.12), transparent 60%),
    linear-gradient(180deg, rgba(10,42,26,.5), rgba(6,30,18,.65));
  border:1px solid rgba(232,182,76,.3);
  border-radius:20px;padding:14px 12px 16px;text-align:center;
  box-shadow:0 12px 30px rgba(0,0,0,.32);
}
.treedraw svg{width:100%;height:auto;display:block;
  filter:drop-shadow(0 8px 14px rgba(0,0,0,.45))}
.tree-count{
  margin-top:10px;font-size:13.5px;color:#cfe6d6;line-height:1.5;
  font-family:Georgia,"Times New Roman",serif;
}
.tree-count strong{color:var(--gold-light);font-size:16px}

/* the baubles catch the light, and the star turns slowly */
.tw-orn{animation:ornshine 3.4s ease-in-out infinite;transform-box:fill-box;transform-origin:center}
@keyframes ornshine{0%,100%{opacity:.88}50%{opacity:1}}
.tw-star{transform-box:fill-box;transform-origin:center;animation:starpulse 3.6s ease-in-out infinite}
@keyframes starpulse{0%,100%{opacity:.9;transform:scale(1)}50%{opacity:1;transform:scale(1.06)}}
@media (prefers-reduced-motion:reduce){
  .tw-orn,.tw-star{animation:none}
}
@media(max-width:899px){
  /* on a narrow screen the tree goes under the list rather than squashing it */
  .treebox{max-width:340px;margin:0 auto}
}

/* The My list tab shares the page with the menus down the right, so its panel
   is a few hundred pixels narrower than the full list screen. It needs more
   room on the window before there is room for a tree beside the gifts, and a
   slimmer tree once there is. */
@media(min-width:900px) and (max-width:1179px){
  #viewMine .listgrid{grid-template-columns:1fr}
  #viewMine .treebox{max-width:340px;margin:0 auto}
}
@media(min-width:1180px){
  #viewMine .listgrid{grid-template-columns:minmax(0,1fr) 260px}
}
/* On the list page the tree sits on the dark page itself, so a see-through
   green over it reads as night. On the My list tab it sits inside a cream
   panel, where the same colour came out a washed-out grey — so here the box
   brings its own dark. */
#viewMine .treebox{
  background:
    radial-gradient(120% 70% at 50% 0%, rgba(232,182,76,.16), transparent 60%),
    linear-gradient(180deg, #0e3d26, #072617);
  border-color:rgba(232,182,76,.42);
}

/* the small lit garland along the top rail of each frame */
.framegarland{
  position:absolute;top:-7px;left:8px;right:8px;height:30px;
  pointer-events:none;z-index:2;
  background-repeat:repeat-x;background-position:center;background-size:auto 100%;
  filter:drop-shadow(0 3px 4px rgba(0,0,0,.45));
}
/* twinkling light dots laid over the garland */
.framegarland .glo{
  position:absolute;top:50%;width:9px;height:9px;margin:-4.5px 0 0 -4.5px;
  border-radius:50%;pointer-events:none;
}
/* The moving half of a garland, sitting exactly on top of the still half.
   Keeping them apart is what stops six blinking lights forcing a repaint of
   several hundred pine needles on every frame. */
.litlayer{position:absolute;left:0;top:0;width:100%;height:100%;pointer-events:none}
.mantel{contain:paint}
.mantel .litlayer{position:absolute;inset:0}
@media(max-width:700px){.framegarland{height:20px;top:-4px;left:5px;right:5px}
  .framegarland .glo{width:7px;height:7px;margin:-3.5px 0 0 -3.5px}}
