/* The playground is a Mac running Moe.
   Nothing here is guessed. The island's outline is IslandShape.swift, its sizes
   are NotchIsland.swift, the glow colours and the light that laps the notch are
   IslandView.swift, the window is MainWindow.swift + Chat/ChatPane.swift, and
   every hex is MoeDesign/Theme.swift. */

:root{
  /* Theme.swift, light */
  --paper:#FCFBF2; --raised:#FFFEF8; --sunk:#F0ECDA; --sidebar:#F5F2E3;
  --ink:#1C1B17; --ink2:#5C594E; --ink3:#6E6A5C;
  --rule:#E3DFCD; --ruleStrong:#D0CBB4;
  --accent:#6B7FD7; --accentDeep:#4D5FB0; --accentTint:#E4E8FB; --onAccent:#fff;
  --warn:#B07D29; --bad:#B0453C;
  /* Theme.Island — the five states of the glow */
  --g-idle:#8CB3D9; --g-listen:#59D98C; --g-think:#73BFF2; --g-speak:#73D9B3;
  --g-dictation:#B79AF5; --g-amber:#E8A64A;
  /* hardware */
  --bar:32px; --notch-w:187px;
  --ui:-apple-system,BlinkMacSystemFont,"SF Pro Text","Helvetica Neue",Helvetica,sans-serif;
  --serif:ui-serif,"New York",Georgia,"Times New Roman",serif;
  --mono:ui-monospace,SFMono-Regular,"SF Mono",Menlo,monospace;
}
html,body{height:100%}
body.desk{margin:0;overflow:hidden;background:#000;color:var(--ink);
  font:13px/1.45 var(--ui);-webkit-font-smoothing:antialiased}
.screen{position:relative;width:100%;height:100svh;overflow:hidden;isolation:isolate;
  border-radius:12px}
.wall{position:absolute;inset:0;background:url(/assets/panels/hero.jpg) center 58%/cover no-repeat}
.wall::after{content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(8,10,14,.46) 0,rgba(8,10,14,.34) 5%,
    rgba(8,10,14,.12) 14%,rgba(10,8,5,0) 30%)}

/* ---------------------------- menu bar ---------------------------- */
.menubar{position:absolute;top:0;left:0;right:0;height:var(--bar);z-index:40;
  display:flex;align-items:center;gap:18px;padding:0 14px;color:#fff;font-size:13.5px;
  text-shadow:0 1px 2px rgba(0,0,0,.35);
  -webkit-user-select:none;user-select:none}
.menubar .home{display:grid;place-items:center;width:16px;height:16px;color:inherit;
  text-decoration:none;flex:none}
.menubar .home svg{width:15px;height:15px;display:block}
.menubar .app{font-weight:600;letter-spacing:.01em}
.menubar .mm{opacity:.95;padding:2px 8px;border-radius:6px;cursor:default}
.menubar .mm:hover{background:rgba(255,255,255,.22)}
.mb-right{margin-left:auto;display:flex;align-items:center;gap:14px}
.mb-right .clock{font-variant-numeric:tabular-nums}
.mi{width:17px;height:15px;flex:none;opacity:.95;display:block}
.srcbtn{appearance:none;border:0;background:transparent;font:inherit;color:inherit;
  cursor:pointer;display:inline-flex;align-items:center;gap:6px;padding:2px 8px;
  border-radius:6px;text-shadow:inherit}
.srcbtn:hover,.srcbtn[aria-expanded="true"]{background:rgba(255,255,255,.24)}
.srcbtn .dot{width:7px;height:7px;border-radius:50%;background:var(--g-listen)}

/* ---------------------------- the notch and its light ---------------------------- */
.notch{position:absolute;top:0;left:50%;transform:translateX(-50%);
  width:var(--notch-w);height:var(--bar);background:#000;z-index:60;
  border-radius:0 0 13px 13px;pointer-events:none}

/* The filled halo: a band of light spilling out around the notch's edges. The
   part over the notch is invisible because the notch is a hole, not a screen. */
.halo{position:absolute;top:-7px;left:50%;transform:translateX(-50%);z-index:52;
  width:calc(var(--notch-w) + 30px);height:calc(var(--bar) + 20px);
  border-radius:22px;pointer-events:none;filter:blur(9px);
  background:var(--halo-c,#E8F1FA);opacity:var(--halo-o,.55);
  transition:opacity .4s ease,background .35s ease}

/* A neon light that runs around the outline of the notch: down one side, across
   the bottom, up the other. A snake, not a clock hand. 2.4s a lap. */
/* above the notch, and just outside its edge: the notch is a hole, so the
   light has to run around the outside of it to be seen at all */
.trail{position:absolute;top:-3px;left:50%;transform:translateX(-50%);z-index:61;
  width:calc(var(--notch-w) + 8px);height:calc(var(--bar) + 6px);
  pointer-events:none;opacity:0;transition:opacity .35s}
.trail[data-on="true"]{opacity:1}
.trail path{fill:none;stroke-linecap:round}
.trail .tail{stroke:var(--g-think);stroke-opacity:.30;stroke-width:1.5;filter:blur(2px)}
.trail .glow{stroke:var(--g-think);stroke-opacity:.9;stroke-width:5.5;filter:blur(5px)}
.trail .head{stroke:var(--g-think);stroke-width:2}
@media (prefers-reduced-motion:no-preference){
  .trail .tail{animation:lap 2.4s linear infinite}
  .trail .glow,.trail .head{animation:lap 2.4s linear infinite}
}
@keyframes lap{from{stroke-dashoffset:0}to{stroke-dashoffset:-100}}

/* ---------------------------- the island ---------------------------- */
/* The bleed has to live on a wrapper: clip-path is applied to the filtered
   result, so a drop-shadow on the clipped element is cut away by its own path. */
.islandwrap{position:absolute;top:0;left:50%;transform:translateX(-50%);z-index:62;
  filter:var(--bleed);pointer-events:none;line-height:0}
.island{position:relative;pointer-events:auto;
  width:var(--notch-w);height:var(--bar);background:#000;overflow:hidden;
  -webkit-clip-path:var(--shape);clip-path:var(--shape);
  transition:width .42s cubic-bezier(.22,1,.36,1),height .42s cubic-bezier(.22,1,.36,1)}
@media (prefers-reduced-motion:reduce){
  .island,.island .inner,.halo,.trail,.hint,.tile{transition:none!important}
  .tile:hover{transform:none}
  .trail .tail,.trail .glow,.trail .head{animation:none}
}
/* visibility switches at once on the way in, so the panel's controls are
   clickable the moment it is open, and only waits on the way out */
.island .inner{position:absolute;left:0;right:0;top:var(--bar);bottom:0;
  display:flex;flex-direction:column;opacity:0;visibility:hidden;
  transition:opacity .2s,visibility 0s .2s;color:#EFECE2;padding:2px 14px 12px}
.island[data-state="peek"] .inner,.island[data-state="open"] .inner{opacity:1;visibility:visible;
  transition:opacity .2s .14s,visibility 0s}
/* Under the island, never over it: at z-index 58 this swallowed every click
   inside the panel, including its own microphone. The island keeps itself open
   with its own pointerenter, so the zone only has to catch the arrival. */
.notch-zone{position:absolute;top:0;left:50%;transform:translateX(-50%);
  width:calc(var(--notch-w) + 110px);height:calc(var(--bar) + 10px);z-index:53;cursor:pointer}

.i-state{flex:none;display:flex;align-items:center;gap:7px;font:600 9px/1 var(--mono);
  letter-spacing:.13em;text-transform:uppercase;color:#8D8880;padding:8px 2px 4px}
.i-state .d{width:6px;height:6px;border-radius:50%;background:var(--g-idle)}
.i-log{flex:1;min-height:0;overflow-y:auto;display:flex;flex-direction:column;gap:11px;
  padding:6px 2px;scrollbar-width:thin}
.i-log:empty::after{content:"Press the microphone and talk, or type.";color:#8D8880;font-size:12.5px}
.i-msg{font-size:13px;line-height:1.45}
.i-msg .w{display:block;font:600 9px/1 var(--mono);letter-spacing:.13em;
  text-transform:uppercase;margin-bottom:4px}
.i-msg.you .w{color:#8FD0A8}
.i-msg.moe .w{color:#6FC9E8}
.i-msg .x{color:#EFECE2}
.i-msg.err .x{color:#E26055}
.i-form{display:flex;gap:8px;align-items:center;flex:none;padding-top:9px;
  border-top:1px solid rgba(255,255,255,.07)}
.i-form input{flex:1;min-width:0;background:rgba(255,255,255,.07);color:#EFECE2;
  border:1px solid rgba(255,255,255,.12);border-radius:8px;padding:8px 10px;
  font:400 13px/1 var(--ui)}
.i-form input::placeholder{color:#8D8880}
.i-form input:focus{outline:1.5px solid var(--g-think);outline-offset:0}

.mic{appearance:none;flex:none;width:31px;height:31px;border-radius:50%;cursor:pointer;
  border:1px solid rgba(255,255,255,.16);background:rgba(255,255,255,.08);
  display:grid;place-items:center;color:#CFCABC;position:relative}
.mic:hover{background:rgba(255,255,255,.16)}
.mic[data-on="true"]{background:var(--g-listen);border-color:var(--g-listen);color:#0d2417}
.mic svg{width:14px;height:14px;display:block}

/* ---------------------------- sources popover ---------------------------- */
.pop{position:absolute;top:calc(var(--bar) + 4px);right:10px;z-index:70;width:282px;
  padding:13px;background:rgba(252,251,242,.84);backdrop-filter:saturate(180%) blur(30px);
  -webkit-backdrop-filter:saturate(180%) blur(30px);color:var(--ink);
  border:.5px solid rgba(0,0,0,.16);border-radius:12px;
  box-shadow:0 20px 50px -14px rgba(0,0,0,.44);display:none}
.pop[data-open="true"]{display:block}
.pop h3{margin:0 0 2px;font:600 13px/1.3 var(--ui)}
.pop .sub{margin:0 0 11px;font-size:12px;color:var(--ink2)}
.srcrail{display:grid;gap:4px}
.src{display:flex;align-items:center;gap:8px;width:100%;text-align:left;cursor:pointer;
  background:transparent;border:1px solid transparent;border-radius:7px;padding:7px 9px;
  font:400 13px/1 var(--ui);color:var(--ink)}
.src .d{width:7px;height:7px;border-radius:50%;background:var(--ink3);flex:none}
.src.on{background:var(--accentTint);border-color:rgba(107,127,215,.28)}
.src.on .d{background:var(--accent)}
.src:hover{background:rgba(0,0,0,.05)}
.src.on:hover{background:var(--accentTint)}

/* ---------------------------- the app window ---------------------------- */
/* MainWindow: sidebar 186. ChatPane: conversations 172, a hairline, the thread. */
.win{position:absolute;z-index:30;left:50%;top:50%;transform:translate(-50%,-50%);
  width:min(1000px,calc(100vw - 40px));height:min(600px,calc(100svh - 120px));
  display:none;grid-template-columns:186px 172px minmax(0,1fr);overflow:hidden;
  background:var(--sidebar);border-radius:16px;
  box-shadow:0 0 0 .5px rgba(0,0,0,.28),0 24px 60px -12px rgba(0,0,0,.42),
    0 6px 16px rgba(0,0,0,.16)}
.win[data-open="true"]{display:grid}
.side{background:var(--sidebar);display:flex;flex-direction:column;gap:1px;
  padding:0 6px 8px}
.tl{display:flex;gap:8px;height:34px;align-items:center;padding-left:7px;flex:none;
  cursor:default;touch-action:none}

.tl button{width:12px;height:12px;border-radius:50%;border:0;padding:0;cursor:pointer;
  box-shadow:inset 0 0 0 .5px rgba(0,0,0,.08);position:relative;
  font:700 9px/12px var(--ui);color:transparent}
.tl:hover button{color:rgba(0,0,0,.62)}
.tl .c{background:#FF5F57}.tl .m{background:#FEBC2E}.tl .z{background:#28C840}
.grp{font:600 9px/1 var(--ui);letter-spacing:1.1px;
  color:var(--ink3);padding:16px 8px 4px}
.row{display:flex;align-items:center;gap:8px;border:0;background:transparent;cursor:pointer;
  border-radius:8px;padding:6px 8px;font:400 12px/1 var(--ui);color:var(--ink2);text-align:left}
.row:hover{background:rgba(28,27,23,.04)}
.row[aria-current="true"]{background:rgba(107,127,215,.13);color:var(--ink);font-weight:600}
.row .g{width:14px;text-align:center;opacity:.8;font-size:11px}
.side .spacer{flex:1}
.side .foot{font-size:10.5px;color:var(--ink3);padding:8px;border-top:1px solid var(--rule);
  display:flex;align-items:center;gap:6px;margin-top:6px}
.side .foot .d{width:6px;height:6px;border-radius:50%;background:#4E7A52}

.convos{background:var(--paper);border-right:1px solid var(--rule);
  display:flex;flex-direction:column;padding:16px 6px 12px;
  border-radius:11px 0 0 11px;border:1px solid var(--rule);border-right-width:1px;
  margin:6px 0 6px 0}
.convos .h{display:flex;align-items:center;padding:0 6px 8px;
  font:600 9px/1 var(--ui);letter-spacing:1.1px;color:var(--ink3)}
.convos .h button{margin-left:auto;border:0;background:transparent;cursor:pointer;
  color:var(--ink3);font-size:12px;padding:0}
.day{font:600 9px/1 var(--ui);letter-spacing:1.1px;
  color:var(--ink3);padding:12px 8px 4px}
.convo{display:block;width:100%;text-align:left;border:0;background:transparent;cursor:pointer;
  border-radius:8px;padding:7px 8px;font:400 12px/1.35 var(--ui);color:var(--ink2)}
.convo[aria-current="true"]{background:rgba(107,127,215,.13);color:var(--ink)}
.convo:hover{background:rgba(28,27,23,.04)}

.thread{display:flex;flex-direction:column;min-width:0;background:var(--raised);
  border-radius:0 11px 11px 0;border:1px solid var(--rule);border-left:0;
  margin:6px 6px 6px 0;overflow:hidden}
.live{display:none;align-items:center;gap:8px;padding:8px 32px;background:var(--accentTint);
  font:400 11px/1 var(--ui);color:var(--ink2);flex:none}
.live[data-on="true"]{display:flex}
.live .d{width:6px;height:6px;border-radius:50%;background:var(--ink3)}
.live[data-mode="listening"] .d{background:var(--bad)}
.live .end{margin-left:auto;border:0;background:transparent;cursor:pointer;
  font:600 11px/1 var(--ui);color:var(--accentDeep)}
.turns{flex:1;min-height:0;overflow-y:auto;padding:24px 32px;display:flex;
  flex-direction:column;gap:20px}
.greet h2{font:400 30px/1.15 var(--serif);color:var(--ink);margin:4px 0 8px}
.greet p{margin:0;font:400 15px/1.5 var(--serif);color:var(--ink2);max-width:560px}
.turn .m{display:flex;gap:8px;align-items:baseline;margin-bottom:6px}
.turn .l{font:600 9px/1 var(--ui);letter-spacing:1.1px;color:var(--ink3)}
.turn .t{font:400 9px/1 var(--mono);color:var(--ink3)}
.turn p{margin:0;font:400 15px/1.5 var(--serif);color:var(--ink2);max-width:560px}
.turn.err p{color:#8c342b}
.compose{flex:none;display:flex;gap:8px;align-items:center;padding:12px 32px 20px;
  border-top:1px solid var(--rule)}
.compose input{flex:1;min-width:0;background:var(--paper);border:1px solid var(--ruleStrong);
  border-radius:10px;padding:10px 12px;font:400 13.5px/1 var(--ui);color:var(--ink)}
.compose input:focus{outline:2px solid var(--accent);outline-offset:-1px}
.compose .mic{border-color:var(--ruleStrong);background:var(--paper);color:var(--ink2)}
.compose .mic[data-on="true"]{background:var(--bad);border-color:var(--bad);color:#fff}
.compose .send{appearance:none;border:0;cursor:pointer;background:var(--accent);
  color:var(--onAccent);border-radius:10px;padding:10px 16px;font:600 13px/1 var(--ui)}
.tips{display:flex;gap:6px;flex-wrap:wrap;padding:0 32px 4px;flex:none}
.tip{appearance:none;cursor:pointer;background:var(--sunk);border:1px solid var(--rule);
  color:var(--ink2);border-radius:999px;padding:6px 11px;font:400 12px/1 var(--ui)}
.tip:hover{background:var(--accentTint);color:var(--accentDeep);border-color:rgba(107,127,215,.3)}

/* ---------------------------- the dock ---------------------------- */
.dock{position:absolute;left:50%;bottom:6px;transform:translateX(-50%);z-index:35;
  display:flex;align-items:flex-end;gap:5px;padding:5px 5px 11px;
  background:rgba(255,255,255,.2);backdrop-filter:saturate(190%) blur(26px);
  -webkit-backdrop-filter:saturate(190%) blur(26px);
  border:.5px solid rgba(255,255,255,.18);border-radius:30px;
  box-shadow:0 14px 40px -10px rgba(0,0,0,.5),inset 0 1px 0 rgba(255,255,255,.55)}
.tile{position:relative;width:64px;height:64px;border-radius:14px;border:0;cursor:pointer;
  padding:0;display:grid;place-items:center;font:600 23px/1 var(--ui);color:#fff;
  box-shadow:0 3px 8px -2px rgba(0,0,0,.4),inset 0 1px 0 rgba(255,255,255,.34)}
.tile .run{position:absolute;bottom:-7px;left:50%;transform:translateX(-50%);
  width:4.5px;height:4.5px;border-radius:50%;background:rgba(0,0,0,.55);opacity:0}
.tile[data-running="true"] .run{opacity:1}
.tile.moe{background:#fff url(/assets/icon-180.png) center/cover}
.dock .sep{width:1px;height:44px;background:rgba(255,255,255,.18);margin:0 4px;
  align-self:center}
.dock .trash{background:linear-gradient(180deg,#dfe5ea,#b9c3cc);color:#4a5560}

.hint{position:absolute;top:calc(var(--bar) + 12px);left:50%;transform:translateX(-50%);
  z-index:50;color:#fff;font-size:12px;padding:5px 11px;border-radius:999px;
  background:rgba(0,0,0,.4);backdrop-filter:blur(10px);transition:opacity .4s;
  pointer-events:none}
.hint[data-gone="true"]{opacity:0}

@media (max-width:900px){
  .win{grid-template-columns:186px minmax(0,1fr)}
  .convos{display:none}
}
@media (max-width:760px){
  .menubar .mm{display:none}
  .win{width:calc(100vw - 16px);height:calc(100svh - 140px);
    grid-template-columns:1fr;grid-template-rows:auto minmax(0,1fr)}
  /* the close button lives in the sidebar, so the sidebar collapses to just it */
  .side{display:flex;flex-direction:row;align-items:center;padding:0 8px;
    border-right:0;border-bottom:1px solid var(--rule)}
  .side .grp,.side .row,.side .foot,.side .spacer{display:none}
  .side .tl{height:36px}
  .dock{gap:4px;padding:5px 7px}
  .tile{width:36px;height:36px;border-radius:9px;font-size:14px}
  .dock .tile:nth-child(n+9):not(.moe){display:none}
}

/* the head runs ahead of its own tail */
@keyframes lapHead{from{stroke-dashoffset:-15}to{stroke-dashoffset:-115}}
.trail .tail{stroke-dasharray:20 80}
.trail .glow,.trail .head{stroke-dasharray:5 95}
@media (prefers-reduced-motion:no-preference){
  .trail .glow,.trail .head{animation-name:lapHead}
}

/* dock icons, drawn rather than borrowed */
.tile.finder{background:linear-gradient(180deg,#4db8f5,#1f7fd6)}
.tile.launchpad{background:linear-gradient(180deg,#eef2f6,#cfd8e0);color:#5a6672}
.tile.safari{background:linear-gradient(180deg,#e9f4fc,#bcd9ee);color:#e8453c}
.tile.messages{background:linear-gradient(180deg,#6ee06f,#22a03a)}
.tile.mail{background:linear-gradient(180deg,#5cb6f8,#1d78d4)}
.tile.maps{background:linear-gradient(180deg,#8ee08a,#4aa8d8)}
.tile.photos{background:linear-gradient(180deg,#fff,#f0f0f2);color:#f2b01e}
.tile.facetime{background:linear-gradient(180deg,#5ee06a,#1f9c39)}
.tile.calendar{background:linear-gradient(180deg,#fff,#ececec);color:#e0453a;font-size:16px}
.tile.contacts{background:linear-gradient(180deg,#f6f2ea,#ded5c6);color:#8a7c66}
.tile.reminders{background:linear-gradient(180deg,#fff,#f1f1f3);color:#4a90d9;font-size:14px}
.tile.notes{background:linear-gradient(180deg,#ffe07a,#f2b52a);color:#6a4906;font-size:14px}
.tile.music{background:linear-gradient(180deg,#fb5c74,#e0304b)}
.tile.appstore{background:linear-gradient(180deg,#4aa8f0,#1f6fd0)}
.tile.settings{background:linear-gradient(180deg,#9aa4ae,#69737d)}

/* the beat before the first token arrives */
.waiting{opacity:.5;animation:breathe 1.15s ease-in-out infinite}
@keyframes breathe{0%,100%{opacity:.28}50%{opacity:.72}}
@media (prefers-reduced-motion:reduce){.waiting{animation:none}}

/* announced, not seen */
.sr{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}

/* what the playground is, said before anyone types into it */
.greet .disclose{margin-top:14px;font-size:12.5px;color:var(--ink3);max-width:58ch}
.greet .disclose a{color:var(--accentDeep)}

/* a dock cannot be wider than the screen it sits on */
.dock{max-width:calc(100vw - 10px)}
@media (max-width:440px){
  .dock{gap:3px;padding:5px 6px}
  .dock .tile:nth-child(n+7):not(.moe){display:none}
  .dock .tile{width:34px;height:34px;border-radius:9px;font-size:13px}
}

/* the Settings shortcut, and the two states the app's footer shows */
.row.settings{position:relative}
.row .kbd{margin-left:auto;font:400 10px/1 var(--mono);color:var(--ink3)}
.side .foot{display:flex;flex-direction:column;gap:5px;align-items:flex-start}
.side .foot span{display:flex;align-items:center;gap:6px}
.side .foot .d.warn{background:#B07D29}
.tile.downloads{background:linear-gradient(180deg,#7fc4f0,#2f7fc8)}

/* the composer is a card in the app, not a rule with a bordered field on it */
.compose{border-top:0;padding:8px 32px 20px}
.compose .card{flex:1;display:flex;gap:8px;align-items:center;min-width:0;
  background:var(--paper);border:2px solid var(--ruleStrong);border-radius:14px;
  padding:12px 16px}
.compose input{background:transparent;border:0;padding:0;font:400 13px/1.2 var(--ui)}
.compose input:focus{outline:0}
.compose .card:focus-within{border-color:var(--accent)}
.compose .mic{width:26px;height:26px;border:0;background:transparent;color:var(--ink3)}
.compose .mic:hover{background:rgba(28,27,23,.06)}
.compose .send{width:26px;height:26px;border-radius:50%;padding:0;display:grid;
  place-items:center;font:700 13px/1 var(--ui);flex:none}

/* SF Symbols at 12pt in a 16pt slot, per MainWindow */
.row .g{width:16px;height:16px;display:grid;place-items:center;opacity:1}
.row .g svg{width:14px;height:14px;display:block;color:var(--ink3)}
.row[aria-current="true"] .g svg{color:var(--accentDeep)}
