/* 线下 · 我的家 (像素家园), js/apps/offline-home.js. The whole App screen is one pixel world; the chrome around it (status bar, 装修, the card at the
   bottom, dialogs) is white, 2px dark-blue-grey outline, a 3px solid drop shadow and square corners - no beige. Dark / night: #222B3B with #0E131C lines.
   Every dialog is centred; there is no bottom sheet (the 装修 drawer is a toolbar, not a dialog). v3: design _handoff/pixel-home-v3/design.md. */
/* companion.css sets font / :disabled on every `#companion-body button`; the button rules below start with that id too so theirs win */
#v-companion.oh-home .app-top, #v-companion.oh-home #offline-composer { display: none; }
#v-companion.oh-home #companion-body { padding: 0; overflow: hidden; position: relative; flex: 1; min-height: 0; background: #B9D3A8; }
.oh-root {
  --oh-ink: #2E3A4F; --oh-ink2: #5E6C82; --oh-panel: #FFFFFF; --oh-edge: #2E3A4F; --oh-soft: #EEF3F8; --oh-accent: #5B8FD6; --oh-accent-ink: #FFFFFF;
  position: absolute; inset: 0; overflow: hidden; background: #B9D3A8; color: var(--oh-ink); font-family: 'Noto Serif SC', 'Songti SC', serif;
  user-select: none; -webkit-user-select: none; -webkit-tap-highlight-color: transparent; text-align: left;
}
.oh-root.night { --oh-ink: #E8EEF6; --oh-ink2: #9AA8BC; --oh-panel: #222B3B; --oh-edge: #0E131C; --oh-soft: #2C3648; --oh-accent: #7FA7E4; --oh-accent-ink: #0E131C; }
:root[data-theme="dark"] .oh-root { --oh-ink: #E8EEF6; --oh-ink2: #9AA8BC; --oh-panel: #222B3B; --oh-edge: #0E131C; --oh-soft: #2C3648; --oh-accent: #7FA7E4; --oh-accent-ink: #0E131C; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .oh-root { --oh-ink: #E8EEF6; --oh-ink2: #9AA8BC; --oh-panel: #222B3B; --oh-edge: #0E131C; --oh-soft: #2C3648; --oh-accent: #7FA7E4; --oh-accent-ink: #0E131C; }
}
.oh-root button:focus-visible { outline: 2px solid var(--oh-accent); outline-offset: 2px; }
.oh-app { position: absolute; inset: 0; overflow: hidden; }
.oh-world { position: absolute; left: 0; top: 0; z-index: 0; }
.oh-outc { position: absolute; left: 0; top: 0; image-rendering: pixelated; }
/* the night over the yard: above everything outside the house (its clip-path leaves a hole where the room is), below the glow / bubbles / dots */
.oh-outveil { position: absolute; left: 0; top: 0; z-index: 400; background: #1B2340; mix-blend-mode: multiply; opacity: 0; transition: opacity .6s; pointer-events: none; }
.oh-hud { position: absolute; left: 12px; right: 12px; top: calc(10px + var(--sat, 0px)); display: flex; align-items: center; justify-content: space-between; z-index: 5; pointer-events: none; }
.oh-hud > * { pointer-events: auto; }
.oh-status { font-size: 13px; color: var(--oh-ink); letter-spacing: .04em; background: var(--oh-panel); border: 2px solid var(--oh-edge); box-shadow: 0 3px 0 0 var(--oh-edge); padding: 0 12px; min-height: 40px; display: flex; align-items: center; white-space: pre; }
.oh-status b { font-family: inherit; font-weight: 600; font-size: 12px; color: var(--oh-ink); }
#companion-body .oh-pxbtn { min-width: 44px; min-height: 44px; display: flex; align-items: center; justify-content: center; background: var(--oh-panel); color: var(--oh-ink); border: 2px solid var(--oh-edge); box-shadow: 0 3px 0 0 var(--oh-edge); cursor: pointer; font-size: 12px; padding: 0 10px; gap: 6px; border-radius: 0; }
#companion-body .oh-pxbtn:active { transform: translateY(2px); box-shadow: 0 1px 0 0 var(--oh-edge); }
#companion-body .oh-pxbtn svg { width: 18px; height: 18px; shape-rendering: crispEdges; }
#companion-body .oh-pxbtn.on { background: var(--oh-accent); color: var(--oh-accent-ink); }
#companion-body .oh-pxbtn.oh-sm { min-height: 36px; padding: 0 10px; font-size: 12px; box-shadow: 0 2px 0 0 var(--oh-edge); }
#companion-body .oh-pxbtn:disabled { opacity: .4; }
.oh-stage { position: absolute; z-index: auto; touch-action: none; user-select: none; -webkit-user-select: none; }
.oh-stage canvas, .oh-stage img { image-rendering: pixelated; image-rendering: crisp-edges; }
.oh-bgc { position: absolute; left: 0; top: 0; }
.oh-items { position: absolute; left: 0; top: 0; }
.oh-item { position: absolute; pointer-events: none; }
.oh-item img, .oh-item canvas { width: 100%; height: 100%; display: block; -webkit-user-drag: none; }
.oh-item.flip img { transform: scaleX(-1); }
.oh-item.lifted { filter: drop-shadow(0 4px 0 rgba(46, 58, 79, .25)); }
.oh-item.hov { filter: drop-shadow(2px 0 0 #fff) drop-shadow(-2px 0 0 #fff) drop-shadow(0 2px 0 #fff) drop-shadow(0 -2px 0 #fff); }
.oh-stage.pt { cursor: pointer; }
.oh-light { position: absolute; left: 0; top: 0; pointer-events: none; overflow: hidden; z-index: 500; }
.oh-veil { position: absolute; inset: 0; mix-blend-mode: multiply; opacity: 0; transition: opacity .6s; }
.oh-glow { position: absolute; border-radius: 50%; mix-blend-mode: screen; opacity: 0; transition: opacity .6s; background: radial-gradient(circle, rgba(255, 226, 140, .95) 0%, rgba(255, 206, 110, .55) 12%, rgba(255, 190, 90, .25) 34%, rgba(255, 180, 80, 0) 62%); }
.oh-glow.bulb { background: radial-gradient(circle, rgba(255, 232, 160, .9) 0%, rgba(255, 214, 120, .45) 22%, rgba(255, 200, 100, .12) 55%, rgba(255, 190, 90, 0) 75%); }
.oh-marks { position: absolute; left: 0; top: 0; pointer-events: none; z-index: 503; }
.oh-hl { position: absolute; left: 0; top: 0; pointer-events: none; z-index: 501; }
.oh-fx { position: absolute; left: 0; top: 0; pointer-events: none; z-index: 502; }
.oh-spark { position: absolute; width: 20px; height: 20px; margin: -10px 0 0 -10px; filter: drop-shadow(0 0 1px rgba(46, 58, 79, .7)) drop-shadow(0 0 4px rgba(255, 214, 110, .9)); opacity: 0; animation: oh-spark 1.2s steps(6) var(--d, 0s) 3; }
.oh-spark svg { width: 100%; height: 100%; shape-rendering: crispEdges; display: block; }
@keyframes oh-spark { 0% { opacity: 0; transform: scale(.4); } 30% { opacity: 1; transform: scale(1); } 60% { opacity: 1; transform: scale(.7); } 100% { opacity: 0; transform: scale(.3); } }
.oh-newdot { position: absolute; width: 10px; height: 10px; margin: -5px 0 0 -5px; background: #F2708E; border: 2px solid #fff; box-shadow: 0 0 0 1px #2E3A4F; animation: oh-bob 1.6s steps(2) infinite; }
@keyframes oh-bob { 50% { transform: translateY(-3px); } }
/* speech: the nine-slice frame bubble_9slice.png (4 corners of 8x8) and its tail, scaled with the house (--S); ♥ ♪ Zz … are a 14x14 picture instead of words */
.oh-bubble { position: absolute; transform: translate(-50%, -100%); color: #2E3A4F; border: calc(8px * var(--S, 2)) solid transparent; border-image: var(--b9) 8 fill / calc(8px * var(--S, 2)); padding: 0 2px; margin-top: calc(-6px * var(--S, 2)); font-size: 12px; line-height: 14px; white-space: nowrap; animation: oh-pop .25s steps(3); image-rendering: pixelated; }
.oh-bubble:after { content: ''; position: absolute; left: 30%; bottom: calc(-14px * var(--S, 2) + 2px); width: calc(8px * var(--S, 2)); height: calc(6px * var(--S, 2)); background: var(--btail) 0 0 / 100% 100%; image-rendering: pixelated; }
.oh-bubble.emo { border: 0; border-image: none; padding: 0; margin-top: 0; }
.oh-bubble.emo:after { display: none; }
/* the picture is the bubble: 4 frames of 16 x 16 in a row, a loop of .8 s, popping up from half size when it appears; whole pixels only (--S is the house's whole-number scale) */
.emoa { display: block; width: calc(16px * var(--S, 2)); height: calc(16px * var(--S, 2)); background-size: calc(64px * var(--S, 2)) 100%; background-repeat: no-repeat; image-rendering: pixelated; transform-origin: 20% 100%; animation: emoa .8s steps(4) infinite, emopop .24s steps(3) 1; }
@keyframes emoa { from { background-position: 0 0; } to { background-position: calc(-64px * var(--S, 2)) 0; } }
@keyframes emopop { from { transform: scale(.5); } to { transform: scale(1); } }
@media (prefers-reduced-motion: reduce) { .emoa { animation: none; } }
.oh-bubble.zz { animation: oh-float 2.4s steps(6) infinite; }
@keyframes oh-pop { from { transform: translate(-50%, -80%); opacity: 0; } to { transform: translate(-50%, -100%); opacity: 1; } }
@keyframes oh-float { 0% { transform: translate(-50%, -100%); } 50% { transform: translate(-50%, -125%); } 100% { transform: translate(-50%, -100%); } }
.oh-dot { position: absolute; width: 4px; height: 4px; background: #F2708E; animation: oh-blink 1s steps(2) infinite; }
@keyframes oh-blink { 50% { opacity: 0; } }
.oh-parcel { pointer-events: auto; cursor: pointer; }   /* outside the house box, so it has to take the tap itself */
.oh-who { position: absolute; left: 12px; right: 12px; bottom: calc(14px + var(--sab, 0px)); z-index: 5; display: flex; align-items: center; gap: 12px; background: var(--oh-panel); border: 2px solid var(--oh-edge); box-shadow: 0 3px 0 0 var(--oh-edge); padding: 10px 12px; cursor: pointer; color: var(--oh-ink); text-align: left; border-radius: 0; }
.oh-root.deco .oh-who { display: none; }
.oh-av { width: 36px; height: 36px; flex: none; background: #3B4A63; color: #fff; display: flex; align-items: center; justify-content: center; font-size: 16px; border: 2px solid var(--oh-edge); }
.oh-who b { display: block; font-size: 14px; font-weight: 600; }
.oh-who span { font-size: 12px; color: var(--oh-ink2); }
.oh-who .oh-av { color: #fff; font-size: 16px; }
.oh-who .oh-st { margin-left: auto; font-family: inherit; font-size: 10px; color: var(--oh-ink2); white-space: nowrap; }
.oh-hint { position: absolute; left: 50%; transform: translateX(-50%); bottom: calc(84px + var(--sab, 0px)); z-index: 5; font-size: 12px; color: var(--oh-ink); background: var(--oh-panel); border: 2px solid var(--oh-edge); padding: 4px 10px; white-space: nowrap; transition: opacity .6s; pointer-events: none; }
.oh-hint:empty { display: none; }
.oh-root.deco .oh-hint { bottom: calc(206px + var(--sab, 0px)); }
/* 装修 drawer: the only bottom panel - a toolbar. Closed: a row of categories and one row to drag from. Pulled up (the grip): the same categories over a 4-column grid. */
.oh-dock { display: none; position: absolute; left: 0; right: 0; bottom: 0; z-index: 6; background: var(--oh-panel); border-top: 2px solid var(--oh-edge); box-shadow: 0 -3px 0 0 rgba(46, 58, 79, .12); padding: 0 0 calc(10px + var(--sab, 0px)); transition: transform .2s steps(4); }
.oh-root.deco .oh-dock { display: block; }
.oh-dock.away { transform: translateY(calc(100% - 22px)); }
.oh-dock-tools { position: absolute; right: 12px; bottom: calc(100% + 10px); display: flex; gap: 6px; }
#companion-body .oh-grip { display: flex; justify-content: center; align-items: center; width: 100%; height: 22px; min-height: 0; background: none; border: 0; cursor: ns-resize; touch-action: none; padding: 0; border-radius: 0; }
.oh-grip span { width: 40px; height: 4px; background: var(--oh-edge); opacity: .35; }
.oh-dock-top { display: flex; align-items: center; gap: 6px; padding: 0 12px 6px; }
.oh-cats { flex: 1; display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none; padding: 2px 2px 4px; }
.oh-cats::-webkit-scrollbar { display: none; }
#companion-body .oh-cats button { flex: none; min-height: 34px; padding: 0 12px; border: 2px solid var(--oh-edge); background: var(--oh-panel); color: var(--oh-ink); font-size: 12px; cursor: pointer; box-shadow: 0 2px 0 0 var(--oh-edge); border-radius: 0; }
#companion-body .oh-cats button.on { background: var(--oh-edge); color: #fff; }
.oh-dock-row { display: flex; gap: 8px; overflow-x: auto; padding: 2px 12px 6px; touch-action: pan-x; scrollbar-width: none; }
.oh-dock-row::-webkit-scrollbar { display: none; }
#companion-body .oh-dock-row button { position: relative; flex: none; width: 68px; height: 72px; background: var(--oh-soft); border: 2px solid var(--oh-edge); box-shadow: 0 2px 0 0 var(--oh-edge); font-size: 11px; color: var(--oh-ink); display: flex; flex-direction: column; align-items: center; justify-content: flex-end; gap: 3px; padding: 4px 2px; cursor: grab; touch-action: pan-x; user-select: none; -webkit-user-select: none; border-radius: 0; }
.oh-dock-row img { max-width: 50px; max-height: 40px; image-rendering: pixelated; pointer-events: none; -webkit-user-drag: none; }
.oh-dock-row .cnt { position: absolute; right: 3px; top: 3px; font-style: normal; font-family: inherit; font-size: 10px; min-width: 14px; height: 14px; line-height: 14px; background: var(--oh-accent); color: var(--oh-accent-ink); }
#companion-body .oh-dock-row button.pick { background: var(--oh-accent); color: var(--oh-accent-ink); }
.oh-dock.open .oh-dock-row { scrollbar-width: none; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); max-height: min(46vh, 330px); overflow-y: auto; overflow-x: hidden; touch-action: pan-y; }
.oh-dock.open .oh-dock-row::-webkit-scrollbar { display: none; }
#companion-body .oh-dock.open .oh-dock-row button { width: auto; touch-action: pan-y; }
#companion-body .oh-dock-row .look { cursor: pointer; }
.oh-dock-row .look img { width: 48px; height: 36px; max-width: none; max-height: none; border: 2px solid var(--oh-edge); }
#companion-body .oh-dock-row .look.on { background: var(--oh-accent); color: var(--oh-accent-ink); }
#companion-body .oh-dock-row .invc { width: auto; min-width: 96px; height: 56px; justify-content: center; cursor: pointer; }
.oh-invc span, .oh-dock-row .invc span { color: var(--oh-ink2); }
.oh-gi, .oh-inv .gi, .oh-dock-row .invc .gi { width: 24px; height: 24px; image-rendering: pixelated; }
.oh-dock-empty { font-size: 12px; color: var(--oh-ink2); padding: 18px 4px; }
.oh-seltools { position: absolute; z-index: 600; display: none; gap: 4px; transform: translateX(-50%); }
.oh-seltools.show { display: flex; }
#companion-body .oh-seltools button { min-height: 36px; min-width: 44px; padding: 0 8px; font-size: 12px; background: var(--oh-panel); color: var(--oh-ink); border: 2px solid var(--oh-edge); box-shadow: 0 2px 0 0 var(--oh-edge); cursor: pointer; border-radius: 0; }
#companion-body .oh-seltools button:active { transform: translateY(2px); box-shadow: none; }
#companion-body .oh-seltools button:disabled { opacity: .4; }
/* dialogs: always centred */
.oh-sheet { position: absolute; left: 50%; top: 50%; width: calc(100% - 40px); max-width: 340px; max-height: 76%; overflow: auto; scrollbar-width: none; transform: translate(-50%, -46%) scale(.94); opacity: 0; visibility: hidden; transition: transform .18s steps(4), opacity .18s steps(4), visibility 0s .18s; background: var(--oh-panel); color: var(--oh-ink); border: 2px solid var(--oh-edge); box-shadow: 0 4px 0 0 var(--oh-edge); padding: 14px 14px 16px; z-index: 20; }
.oh-sheet.show { transform: translate(-50%, -50%) scale(1); opacity: 1; visibility: visible; transition: transform .18s steps(4), opacity .18s steps(4); }
.oh-sheet::-webkit-scrollbar { display: none; }
.oh-sheet:focus, .oh-sheet:focus-visible { outline: none !important; }   /* the dialog itself takes focus on open (Esc / Tab work from there); the ring belongs on buttons */
.oh-sheet h3 { margin: 0 0 4px; font-size: 16px; font-weight: 600; font-family: inherit; }
.oh-sub { font-size: 12px; color: var(--oh-ink2); margin-bottom: 12px; }
#companion-body .oh-sheet .oh-close { position: absolute; right: 10px; top: 8px; min-width: 44px; min-height: 44px; background: none; border: 0; font-size: 20px; color: var(--oh-ink); cursor: pointer; }
.oh-four { display: flex; justify-content: space-around; margin: 4px 0 12px; }
.oh-four canvas { width: 72px; height: 84px; image-rendering: pixelated; }
/* 衣柜: one button per outfit - its front picture and its name; the one on is highlighted */
.oh-outfits { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin: 0 0 12px; }
#companion-body .oh-outfits button { display: flex; flex-direction: column; align-items: center; gap: 4px; min-height: 108px; padding: 6px 4px; background: var(--oh-soft); border: 2px solid var(--oh-edge); box-shadow: 0 2px 0 0 var(--oh-edge); color: var(--oh-ink); font-size: 13px; cursor: pointer; border-radius: 0; }
#companion-body .oh-outfits button.on { background: var(--oh-accent); color: var(--oh-accent-ink); }
.oh-outfits canvas { width: 48px; height: 56px; image-rendering: pixelated; }
.oh-opts { display: flex; flex-direction: column; gap: 10px; }
.oh-opt { display: flex; align-items: center; gap: 12px; text-align: left; background: var(--oh-soft); border: 2px solid var(--oh-edge); box-shadow: 0 3px 0 0 var(--oh-edge); padding: 12px; color: var(--oh-ink); cursor: pointer; min-height: 64px; border-radius: 0; }
.oh-opt:active { transform: translateY(2px); box-shadow: 0 1px 0 0 var(--oh-edge); }
.oh-opt .ic { width: 36px; height: 36px; flex: none; image-rendering: pixelated; }
.oh-opt b { display: block; font-size: 15px; font-weight: 600; }
.oh-opt span { font-size: 12px; color: var(--oh-ink2); }
.oh-paper { background: #FFFFFF linear-gradient(transparent 23px, #E3ECF6 24px) 0 10px / 100% 24px; color: #2E3A4F; border: 2px solid #2E3A4F; padding: 14px; font-size: 14px; line-height: 24px; box-shadow: 0 3px 0 0 #2E3A4F; }
.oh-paper + .oh-paper { margin-top: 10px; }
.oh-paper small { display: block; text-align: right; color: #55657B; margin-top: 6px; }
.oh-cal-row { display: flex; gap: 12px; align-items: center; padding: 10px 0; border-bottom: 1px dashed var(--oh-ink2); font-size: 14px; }
.oh-cal-row:last-child { border-bottom: 0; }
.oh-cal-row .d { font-family: inherit; font-size: 12px; min-width: 56px; color: var(--oh-accent); }
#companion-body .oh-primary { width: 100%; min-height: 48px; background: var(--oh-accent); color: var(--oh-accent-ink); border: 2px solid var(--oh-edge); box-shadow: 0 3px 0 0 var(--oh-edge); font-size: 14px; cursor: pointer; margin-top: 12px; border-radius: 0; }
.oh-scrim { position: absolute; inset: 0; background: rgba(20, 24, 36, .35); opacity: 0; pointer-events: none; transition: opacity .2s; z-index: 19; }
.oh-scrim.show { opacity: 1; pointer-events: auto; }
/* the phone's screen going off / coming back on (进门 / 回小手机 / 出门) */
.oh-tv { position: absolute; inset: 0; background: #0E1118; z-index: 50; display: flex; align-items: center; justify-content: center; transition: opacity .6s; }
.oh-tv.gone { opacity: 0; pointer-events: none; }
.oh-tv.quick { transition: opacity .3s; }
.oh-scr { width: 150px; height: 300px; background: #DCE7F2; border: 6px solid #2A303C; border-radius: 22px; transition: all .45s cubic-bezier(.5, 0, .9, .4); }
.oh-scr.off { height: 4px; width: 150px; border-radius: 2px; background: #fff; border-color: transparent; }
.oh-scr.dot { height: 4px; width: 4px; border-radius: 2px; }
.oh-scr.none { opacity: 0; }
.oh-toast { position: absolute; left: 50%; top: 40%; transform: translate(-50%, -50%); padding: 8px 14px; background: var(--oh-edge); color: #FFFFFF; font-size: 13px; opacity: 0; pointer-events: none; transition: opacity .2s; z-index: 60; max-width: 80%; text-align: center; }
.oh-toast.show { opacity: 1; }
/* v3 dialogs: one head (a 48x48 pixel tile + title + one line), an optional 展示区, 信纸卡, the rows of an order, the 物品栏 */
.oh-shead { display: flex; gap: 12px; align-items: center; margin: 0 40px 14px 0; }
.oh-sh h3 { margin: 0; }
.oh-sh .oh-sub { margin: 2px 0 0; }
.oh-stile { flex: none; width: 48px; height: 48px; display: flex; align-items: center; justify-content: center; background: var(--oh-soft); border: 2px solid var(--oh-edge); box-shadow: 0 2px 0 0 var(--oh-edge); }
.oh-stile img { image-rendering: pixelated; max-width: 42px; max-height: 42px; object-fit: contain; }
.oh-stile.oh-av2 { color: #fff; font-size: 16px; font-weight: 600; }
.oh-hero { position: relative; display: flex; align-items: flex-end; justify-content: center; height: 128px; margin: 0 0 12px; border: 2px solid var(--oh-edge); background: var(--oh-soft) radial-gradient(circle at 1px 1px, rgba(91, 143, 214, .18) 1px, transparent 1.5px) 0 0 / 10px 10px; padding-bottom: 14px; }
.oh-hero img { image-rendering: pixelated; position: relative; z-index: 1; }
.oh-hero::after { content: ''; position: absolute; left: 50%; bottom: 10px; width: 96px; height: 6px; transform: translateX(-50%); background: rgba(46, 58, 79, .12); }
.oh-pbox { position: relative; width: 120px; height: 84px; z-index: 1; }
.oh-pbox canvas { position: absolute; image-rendering: pixelated; }
.oh-pbox canvas[data-oh="pc"] { left: 0; bottom: 0; width: 120px; height: 84px; }
.oh-pbox canvas[data-oh="pClip"] { opacity: 0; }
.oh-pbox.open canvas[data-oh="pClip"] { animation: oh-clipup .5s steps(5) forwards; }
@keyframes oh-clipup { from { opacity: 0; transform: translateY(24px); } to { opacity: 1; transform: translateY(-6px); } }
.oh-letter { position: relative; background: var(--oh-panel); border: 2px solid var(--oh-edge); box-shadow: 0 3px 0 0 var(--oh-edge); padding: 12px 14px 14px; margin-bottom: 4px; }
.oh-letter + .oh-sheetbtns, .oh-hero + .oh-sheetbtns, .oh-rows + .oh-sheetbtns, .oh-paper + .oh-sheetbtns { margin-top: 12px; }
.oh-lh { display: flex; align-items: center; gap: 8px; font-size: 13px; }
.oh-lav { width: 24px; height: 24px; display: inline-flex; align-items: center; justify-content: center; color: #fff; font-size: 12px; }
.oh-when { color: var(--oh-ink2); font-size: 11px; margin-left: auto; margin-right: 34px; }
.oh-stamp { position: absolute; right: 10px; top: 8px; width: 26px; height: 30px; background: #F7FAFD; border: 2px dashed var(--oh-accent); box-shadow: inset 0 0 0 3px #F7FAFD, inset 0 0 0 30px #DCEBF7; }
.oh-stamp::after { content: ''; position: absolute; left: 7px; top: 8px; width: 8px; height: 8px; background: #F2A7BB; box-shadow: -3px -3px 0 -1px #F2A7BB, 3px -3px 0 -1px #F2A7BB; }
.oh-letter p { margin: 10px 0 0; font-size: 14px; line-height: 22px; color: var(--oh-ink); overflow-wrap: anywhere; }
.oh-rows { border: 2px solid var(--oh-edge); margin-bottom: 4px; }
.oh-row { display: flex; justify-content: space-between; gap: 12px; padding: 10px 12px; font-size: 14px; }
.oh-invgrid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.oh-inv { display: flex; justify-content: space-between; align-items: center; min-height: 44px; padding: 0 10px; border: 2px solid var(--oh-edge); background: var(--oh-soft); font-size: 13px; }
.oh-inv span { color: var(--oh-ink2); }
.oh-inv b { flex: 1; margin-left: 6px; font-weight: 400; overflow-wrap: anywhere; }
.oh-sheetbtns { display: flex; gap: 8px; }
#companion-body .oh-sheetbtns .oh-pxbtn { flex: 1; min-height: 44px; }
#companion-body .oh-sheetbtns .oh-pxbtn:first-child { background: var(--oh-accent); color: var(--oh-accent-ink); }
#companion-body .oh-sheetbtns .oh-pxbtn.g { background: var(--oh-panel); color: var(--oh-ink); }
/* small things standing on furniture (the prop is an .oh-item in the room's layer; the ones outside the door take the tap themselves) */
.oh-item.oh-prop img { width: 100%; height: 100%; image-rendering: pixelated; }
.oh-steam { position: absolute; left: 30%; top: -60%; width: 40%; height: 60%; background: linear-gradient(90deg, transparent 0 30%, rgba(255, 255, 255, .85) 30% 45%, transparent 45% 65%, rgba(255, 255, 255, .7) 65% 80%, transparent 80%); animation: oh-steam 1.6s steps(4) infinite; }
@keyframes oh-steam { 0% { opacity: 0; transform: translateY(4px); } 50% { opacity: 1; } 100% { opacity: 0; transform: translateY(-6px); } }
.oh-glow.jar { background: none; border-radius: 0; mix-blend-mode: normal; }
.oh-glow.jar img { width: 100%; height: 100%; image-rendering: pixelated; filter: drop-shadow(0 0 2px #FFE9A0) drop-shadow(0 0 5px rgba(255, 226, 140, .9)); }
.oh-occl { image-rendering: pixelated; }
@media (prefers-reduced-motion: reduce) {
  .oh-steam, .oh-pbox.open canvas[data-oh="pClip"] { animation: none; }
  .oh-pbox.open canvas[data-oh="pClip"] { opacity: 1; }
  .oh-spark, .oh-newdot, .oh-dot, .oh-bubble { animation: none; }
  .oh-spark { opacity: 1; }
  .oh-sheet, .oh-sheet.show, .oh-tv, .oh-scr { transition: none; }
}

/* ── 木牌: the status sign, the HUD buttons (home, map, shop), the card at the bottom and the hint share one wooden look; the colour is fixed 原木.
   Design: _handoff/offline-cafe/offline-prototype-v53.html ── */
.oh-root { --sw: #C89058; --sw2: #B97F4A; --shl: #DDA870; --sed: #5E3B1E; --sink: #FFF6E6; }
.oh-hud .oh-status, .ot-hud .oh-status, #companion-body .oh-hud .oh-pxbtn, #companion-body .ot-hud .oh-pxbtn, #companion-body .oh-who {
  background: var(--sw) repeating-linear-gradient(0deg, var(--sw) 0 6px, var(--sw2) 6px 7px); color: var(--sink); border: 2px solid var(--sed);
  box-shadow: 0 3px 0 0 var(--sed), inset 0 2px 0 0 var(--shl); }
.oh-hud .oh-status, .ot-hud .oh-status, #companion-body .oh-hud .oh-pxbtn, #companion-body .ot-hud .oh-pxbtn { position: relative; }   /* the card at the bottom stays absolute */
#companion-body .oh-hud .oh-pxbtn:active, #companion-body .ot-hud .oh-pxbtn:active { box-shadow: 0 1px 0 0 var(--sed), inset 0 2px 0 0 var(--shl); }
.oh-hud .oh-status, .ot-hud .oh-status { gap: 6px; padding: 0 14px; }
.oh-hud .oh-status b, .ot-hud .oh-status b { color: var(--sink); }
.oh-hud .oh-status::before, .oh-hud .oh-status::after, .ot-hud .oh-status::before, .ot-hud .oh-status::after { content: ""; position: absolute; top: 4px; width: 3px; height: 3px; background: var(--sed); }
.oh-hud .oh-status::before, .ot-hud .oh-status::before { left: 4px; }
.oh-hud .oh-status::after, .ot-hud .oh-status::after { right: 4px; }
#companion-body .oh-hud .oh-pxbtn.on, #companion-body .ot-hud .oh-pxbtn.on { background: var(--sed); color: #fff; }
.oh-hudr { display: flex; gap: 8px; }
/* the card at the bottom: name · building + place, then what TA is doing; the dots are the page when there is more than one person */
#companion-body .oh-who { padding: 8px 10px; gap: 10px; }
#companion-body .oh-who .oh-av { width: 34px; height: 34px; border: 2px solid var(--sed); box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .25); font-size: 15px; }
.oh-who .oh-wt { min-width: 0; flex: 1; }
.oh-who b { display: flex; align-items: center; gap: 6px; color: var(--sink); font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.oh-who b img { height: 14px; image-rendering: pixelated; flex: none; }
.oh-who .oh-ws { display: block; color: var(--sink); opacity: .78; font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.oh-who .oh-st { display: flex; gap: 4px; margin-left: auto; }
.oh-who .oh-st:empty { display: none; }
.oh-who .oh-st i { width: 5px; height: 5px; background: var(--sed); opacity: .3; display: block; }
.oh-who .oh-st i.on { opacity: 1; }
.oh-hint { background: var(--sw); color: var(--sink); border: 2px solid var(--sed); box-shadow: 0 2px 0 0 var(--sed); display: flex; align-items: center; gap: 6px; }
.oh-hint img { width: 14px; height: 14px; image-rendering: pixelated; }
/* 他们此刻 */
.oh-pcard { display: grid; grid-template-columns: 40px minmax(0, 1fr) auto; gap: 4px 10px; align-items: center; padding: 10px; margin-top: 8px; background: var(--oh-soft); border: 2px solid var(--oh-edge); box-shadow: 0 2px 0 0 var(--oh-edge); }
.oh-pcard .oh-av { width: 40px; height: 40px; grid-row: span 2; }
.oh-pnm { font-size: 14px; font-weight: 600; display: flex; align-items: center; gap: 6px; min-width: 0; }
.oh-ptx { font-size: 12px; color: var(--oh-ink2); min-width: 0; }
.oh-pchip { display: inline-flex; align-items: center; gap: 4px; font-size: 11px; font-weight: 400; padding: 1px 6px; border: 2px solid var(--oh-edge); background: var(--oh-panel); white-space: nowrap; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.oh-pchip img { height: 12px; image-rendering: pixelated; }
.oh-pill { font-size: 11px; padding: 2px 6px; border: 2px solid var(--oh-edge); white-space: nowrap; justify-self: end; }
.oh-pill:empty { visibility: hidden; }
.oh-pill.free { background: #DDF0E2; color: #2E5A3A; } .oh-pill.busy { background: #F3DADA; color: #7A2E2E; } .oh-pill.maybe { background: #FFF1C9; color: #6E5410; }
#companion-body .oh-act { grid-column: 3; justify-self: end; min-height: 44px; padding: 0 12px; font-size: 12px; cursor: pointer; background: var(--oh-accent); color: var(--oh-accent-ink); border: 2px solid var(--oh-edge); box-shadow: 0 2px 0 0 var(--oh-edge); border-radius: 0; }
#companion-body .oh-act.g { background: var(--oh-panel); color: var(--oh-ink); }
/* 外出 */
.oh-opts .oh-opt { background: var(--oh-panel); box-shadow: 0 2px 0 0 var(--oh-edge); padding: 10px 12px; gap: 12px; }
.oh-opts .oh-opt .oh-icw { width: 46px; height: 46px; flex: none; display: flex; align-items: center; justify-content: center; border: 2px solid var(--oh-edge); }
.oh-opts .oh-opt .oh-icw .ic { width: 30px; height: 30px; }
.oh-icw.date { background: #FBE3E8; } .oh-icw.trip { background: #E1EBF8; } .oh-icw.walk { background: #E2F1E2; }
.oh-opts .oh-opt > div { flex: 1; min-width: 0; }
.oh-opts .oh-opt .oh-go { font-family: inherit; font-size: 14px; color: var(--oh-ink2); }
.oh-opts .oh-opt em { font-style: normal; font-size: 10px; padding: 1px 5px; margin-left: 6px; border: 2px solid var(--oh-edge); background: #FFF1C9; color: #6E5410; vertical-align: 2px; }
.oh-opts .oh-opt.soon { opacity: .75; }
/* 线下设置 */
.oh-setsec { padding: 10px 0 12px; border-top: 2px solid var(--oh-edge); }
.oh-setsec:first-of-type { border-top: 0; padding-top: 2px; }
.oh-setsec-h { font-size: 12px; letter-spacing: .08em; color: var(--oh-ink2); margin-bottom: 6px; }
.oh-setline { display: flex; justify-content: space-between; align-items: center; font-size: 13px; font-weight: 600; margin: 10px 0 6px; }
.oh-setopt { display: flex; gap: 6px; }
#companion-body .oh-setopt button { min-height: 44px; font-size: 12px; cursor: pointer; background: var(--oh-soft); color: var(--oh-ink); border: 2px solid var(--oh-edge); box-shadow: 0 2px 0 0 var(--oh-edge); border-radius: 0; }
#companion-body .oh-setopt button { flex: 1; padding: 0 6px; }
#companion-body .oh-setopt button.on { background: var(--oh-accent); color: var(--oh-accent-ink); }
.oh-setnote { font-size: 11px; color: var(--oh-ink2); margin-top: 8px; }
.oh-setline .oh-setsoon { font-style: normal; font-weight: 400; font-size: 10px; padding: 1px 5px; margin-left: 6px; border: 2px solid var(--oh-edge); background: #E7E9EE; color: var(--oh-ink2); vertical-align: 2px; }
/* nothing in the 线下 pages shows a scroll bar (they all still scroll) */
.oh-root, .oh-root * { scrollbar-width: none; -ms-overflow-style: none; }
.oh-root *::-webkit-scrollbar { display: none; width: 0; height: 0; }

/* small things (js/offline-home-small.js): a hop when tapped, the red seal on a wish that came true, and the frosted-glass dialogs of the 信盒 / 集章册 / 纸条 / 愿望 / 票根 / 明信片 */
@keyframes oh-hop { 0% { transform: translateY(0); } 40% { transform: translateY(calc(var(--S, 2) * -2px)); } 100% { transform: translateY(0); } }
.oh-item.bounce { animation: oh-hop .4s steps(4); }
.oh-item .oh-seal { position: absolute; left: 0; top: 0; width: 100%; height: 100%; image-rendering: pixelated; pointer-events: none; }
.oh-sheet.glass { background: color-mix(in srgb, var(--oh-panel) 58%, transparent); -webkit-backdrop-filter: blur(16px) saturate(1.25); backdrop-filter: blur(16px) saturate(1.25); border: 1px solid rgba(255, 255, 255, .5); border-radius: 18px; box-shadow: 0 10px 30px rgba(20, 30, 50, .3); }
.oh-root.night .oh-sheet.glass { border-color: rgba(255, 255, 255, .16); }
.oh-sheet.glass .oh-paper { background-color: color-mix(in srgb, #FFFFFF 78%, transparent); }
.oh-lrows { display: flex; flex-direction: column; gap: 8px; }
#companion-body .oh-lrow { position: relative; display: grid; grid-template-columns: 1fr auto; grid-template-areas: "who pm" "first pm" "when pm"; column-gap: 8px; text-align: left; padding: 8px 10px; min-height: 44px; background: color-mix(in srgb, var(--oh-panel) 70%, transparent); color: var(--oh-ink); border: 1px solid color-mix(in srgb, var(--oh-edge) 28%, transparent); border-radius: 12px; cursor: pointer; font-size: 13px; }
.oh-lrow .oh-lwho { grid-area: who; font-weight: 600; }
.oh-lrow .oh-lwhen { grid-area: when; font-size: 11px; color: var(--oh-ink2); }
.oh-lrow .oh-lfirst { grid-area: first; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.oh-lrow .oh-pm, .oh-pcback .oh-pm { grid-area: pm; width: 60px; height: 26px; align-self: center; opacity: .9; }
.oh-stamps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px 6px; }
.oh-stampcell { position: relative; display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 8px 2px 6px; background: color-mix(in srgb, var(--oh-panel) 60%, transparent); border: 1px solid color-mix(in srgb, var(--oh-edge) 22%, transparent); border-radius: 12px; }
.oh-stampcell canvas { width: 64px; height: 64px; image-rendering: pixelated; }
.oh-stampcell b { font-size: 12px; font-weight: 600; color: var(--oh-ink); }
.oh-stampcell:not(.have) b { color: var(--oh-ink2); font-weight: 400; }
.oh-stampcell small { min-height: 13px; font-size: 11px; color: var(--oh-ink2); }
.oh-stampcell .oh-sheart { position: absolute; right: 6px; top: 6px; width: 14px; height: 12px; background-size: 100% 100%; image-rendering: pixelated; }
.oh-stampcell.fresh canvas { animation: oh-stampdown .5s steps(5) both; }
@keyframes oh-stampdown { 0% { transform: scale(2.4) rotate(-8deg); opacity: 0; } 70% { transform: scale(1.1); opacity: 1; } 100% { transform: scale(1); opacity: 1; } }
.oh-pcback { position: relative; min-height: 132px; padding: 12px 84px 12px 14px; background: color-mix(in srgb, #FFFFFF 72%, transparent); color: #2E3A4F; border: 1px solid rgba(46, 58, 79, .25); border-radius: 12px; }
.oh-pcback p { margin: 0; font-size: 14px; line-height: 22px; overflow-wrap: anywhere; }
.oh-pcback small { display: block; margin-top: 10px; font-size: 12px; color: #55657B; }
.oh-pcback .oh-pcstamp { position: absolute; right: 12px; top: 12px; width: 54px; height: 54px; display: flex; align-items: center; justify-content: center; background: #FFFFFF; outline: 2px dashed rgba(46, 58, 79, .35); outline-offset: -3px; }
.oh-pcback .oh-pcstamp img { width: 36px; height: 36px; image-rendering: pixelated; }
.oh-pcback .oh-pm { position: absolute; right: 6px; top: 62px; }
.oh-sheet.glass::-webkit-scrollbar { display: none; }
@media (prefers-reduced-motion: reduce) { .oh-item.bounce, .oh-stampcell.fresh canvas { animation: none; } }

/* 第二批小物件: the thirsty drop over a plant by the window, the jar in its dialog */
.oh-item .oh-drop { position: absolute; width: calc(var(--S, 2) * 5px); height: calc(var(--S, 2) * 6px); right: calc(var(--S, 2) * -4px); top: calc(var(--S, 2) * -6px); image-rendering: pixelated; pointer-events: none; animation: oh-hop .8s steps(4) infinite; }
.oh-jarhero { width: 70px; height: 98px; image-rendering: pixelated; }
@media (prefers-reduced-motion: reduce) { .oh-item .oh-drop { animation: none; } }

/* 两间房 + 家具动效 (js/apps/offline-home-fx.js): the little animations of the furniture are boxes in the fx layer and classes on the piece for a moment */
.oh-partwall { transition: opacity .15s; }
.oh-root.wallghost .oh-partwall { opacity: .32; pointer-events: none; }   /* 半透明: the wall, its frame and door, a 竖墙 */
.oh-item.oh-partwall.cut { overflow: hidden; box-shadow: 0 -1px 0 0 #B7CDE3; }   /* 矮墙: only the bottom strip */
.oh-item.oh-partwall.cut canvas { position: absolute; left: 0; bottom: 0; height: auto; }
.oh-dock-tools { left: 12px; justify-content: flex-end; }
#companion-body .oh-dock-tools .oh-pxbtn.oh-sm { padding: 0 8px; }
/* 墙纸地板: a centred dialog; the room behind it stays as it is (not dimmed, not blurred) so a change is seen at once */
.oh-root.looking .oh-scrim { background: transparent; }
.oh-root.looking .oh-sheet { max-width: 330px; }
.oh-lk-seg { display: flex; gap: 3px; padding: 3px; margin: 0 auto 10px; width: max-content; max-width: 100%; border-radius: 14px; background: color-mix(in srgb, var(--oh-panel) 70%, transparent); border: 1px solid rgba(255, 255, 255, .5); }
#companion-body .oh-lk-seg button { border: 0; border-radius: 11px; background: transparent; color: var(--oh-ink); font: inherit; font-size: 13px; min-height: 34px; padding: 0 14px; cursor: pointer; }
#companion-body .oh-lk-seg button.on { background: var(--oh-accent); color: var(--oh-accent-ink); }
.oh-lk-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; max-height: min(40vh, 300px); overflow-y: auto; scrollbar-width: none; }
.oh-lk-grid::-webkit-scrollbar { display: none; }
#companion-body .oh-lk-grid button { border: 2px solid var(--oh-edge); background: var(--oh-panel); color: var(--oh-ink); font: inherit; font-size: 11px; padding: 6px 2px; display: flex; flex-direction: column; align-items: center; gap: 4px; cursor: pointer; min-height: 44px; }
#companion-body .oh-lk-grid button.on { border-color: var(--oh-accent); box-shadow: 0 0 0 2px var(--oh-accent); }
.oh-lk-grid button img { width: 48px; height: 36px; image-rendering: pixelated; }
.oh-lk-note { text-align: center; padding: 12px 4px; font-size: 13px; color: var(--oh-ink); opacity: .75; }
.oh-item.oh-prop.wig img { transform-origin: 50% 100%; animation: oh-mailwig 2.6s ease-in-out infinite; }
@keyframes oh-mailwig { 0%, 12% { transform: rotate(0); } 3% { transform: rotate(-4deg); } 6% { transform: rotate(3deg); } 9% { transform: rotate(-2deg); } }
.oh-fxp { position: absolute; pointer-events: none; }
.oh-item.oh-sway img, .oh-item.oh-squash img, .oh-item.oh-tug img, .oh-item.oh-tapb img, .oh-item.oh-shake img, .oh-item.oh-bobm img { animation-delay: var(--fxd, 0ms) !important; transform-origin: 50% 100%; }
.oh-item.oh-sway img { animation: oh-sway 1.1s ease-in-out both; }
@keyframes oh-sway { 0%, 100% { transform: rotate(0); } 20% { transform: rotate(-3deg); } 45% { transform: rotate(2.5deg); } 70% { transform: rotate(-1.5deg); } }
.oh-item.oh-squash img { animation: oh-squash .7s cubic-bezier(.34, 1.6, .64, 1) both; }
@keyframes oh-squash { 0% { transform: scale(1, 1); } 30% { transform: scale(1.14, .78); } 60% { transform: scale(.95, 1.08); } 100% { transform: scale(1, 1); } }
.oh-item.oh-tug img { animation: oh-tug .5s ease-out both; }
@keyframes oh-tug { 0%, 100% { transform: translateY(0); } 35% { transform: translateY(1px) scale(1.02, .98); } }
.oh-item.oh-tapb img, .oh-item.oh-tapb canvas { animation: oh-tapb .45s cubic-bezier(.34, 1.6, .64, 1) both; }
@keyframes oh-tapb { 0% { transform: scale(1, 1); } 25% { transform: scale(1.07, .9); } 55% { transform: scale(.97, 1.06); } 100% { transform: scale(1, 1); } }
.oh-item.oh-shake img { animation: oh-shk .14s steps(2) infinite; }
@keyframes oh-shk { 0% { transform: translate(-1px, 0); } 50% { transform: translate(1px, -1px); } 100% { transform: translate(-1px, 0); } }
.oh-item.oh-bobm img { animation: oh-bobm .6s ease-in-out infinite; }
@keyframes oh-bobm { 50% { transform: scale(1.03, .97); } }
.oh-fxp.drop { width: 2px; height: 3px; background: #7FB2D6; box-shadow: 0 0 0 1px rgba(255, 255, 255, .4); animation: oh-dropf .7s ease-in both; }
@keyframes oh-dropf { 0% { opacity: 0; transform: translateY(0); } 20% { opacity: 1; } 100% { opacity: 0; transform: translateY(var(--py)); } }
.oh-fxp.bub { border: 1px solid #8FC0E4; border-radius: 50%; animation: oh-bubu 1.3s ease-out both; }
@keyframes oh-bubu { 0% { opacity: 0; transform: translate(0, 0) scale(.4); } 30% { opacity: 1; } 100% { opacity: 0; transform: translate(var(--px), var(--py)) scale(1); } }
.oh-fxp.rainl { width: 1px; background: linear-gradient(rgba(160, 205, 235, 0), rgba(160, 205, 235, .95)); animation: oh-rainl .45s linear infinite; }
@keyframes oh-rainl { from { transform: translateY(-6px); opacity: 0; } 30% { opacity: 1; } to { transform: translateY(10px); opacity: 0; } }
.oh-fxp.scrglow { background: rgba(160, 205, 255, .5); box-shadow: 0 0 10px 3px rgba(160, 205, 255, .75); mix-blend-mode: screen; animation: oh-scrfl 1.4s steps(3) infinite; }
.oh-fxp.ovenglow { background: rgba(255, 160, 80, .45); box-shadow: 0 0 10px 4px rgba(255, 150, 70, .6); mix-blend-mode: screen; animation: oh-scrfl 1s steps(3) infinite; }
@keyframes oh-scrfl { 0% { opacity: .55; } 33% { opacity: .85; } 66% { opacity: .65; } 100% { opacity: .8; } }
.oh-fxp.glint { overflow: hidden; }
.oh-fxp.glint::after { content: ''; position: absolute; top: -30%; left: -70%; width: 35%; height: 160%; background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .9), transparent); transform: skewX(-20deg); animation: oh-glintm .9s ease-out both; }
@keyframes oh-glintm { to { left: 130%; } }
.oh-fxp.petal { width: 3px; height: 2px; background: #F2A7BB; animation: oh-fall 2.4s linear both; }
.oh-fxp.snow { width: 2px; height: 2px; background: #FFFFFF; box-shadow: 0 0 0 1px rgba(160, 190, 220, .5); animation: oh-fall 2.4s linear both; }
@keyframes oh-fall { 0% { opacity: 0; transform: translate(0, 0); } 15% { opacity: 1; } 100% { opacity: 0; transform: translate(var(--px), var(--py)) rotate(200deg); } }
.oh-fxp.swirl { border: 2px dotted #7FB2D6; border-radius: 50%; animation: oh-swirl .5s linear 3 both; }
@keyframes oh-swirl { from { transform: rotate(0) scale(.6); } to { transform: rotate(360deg) scale(1); } }
.oh-fxp.flyimg { image-rendering: pixelated; animation: oh-flyb 1.3s cubic-bezier(.3, 1.4, .6, 1) both; }
.oh-fxp.flyimg img { width: 100%; height: 100%; image-rendering: pixelated; }
@keyframes oh-flyb { 0% { opacity: 0; transform: translateY(0) scale(.6); } 30% { opacity: 1; transform: translateY(-14px) scale(1.15); } 80% { opacity: 1; } 100% { opacity: 0; transform: translateY(-20px) scale(1); } }
.oh-fxp.heat { width: 2px; border-left: 1px solid rgba(255, 170, 120, .7); border-radius: 50%; animation: oh-heatw 1.6s ease-out both; }
@keyframes oh-heatw { 0% { opacity: 0; transform: translateY(0) scaleX(1); } 30% { opacity: 1; } 100% { opacity: 0; transform: translateY(-14px) scaleX(-1); } }
.oh-fxp.pstar { width: 14px; height: 14px; margin: -7px 0 0 -7px; animation: oh-pst .7s ease-out both; filter: drop-shadow(0 0 2px rgba(255, 226, 140, .9)); }
.oh-fxp.pstar svg { width: 100%; height: 100%; display: block; shape-rendering: crispEdges; }
@keyframes oh-pst { 0% { opacity: 0; transform: translate(0, 0) scale(.3); } 25% { opacity: 1; } 100% { opacity: 0; transform: translate(var(--px), var(--py)) scale(.9); } }
.oh-fxp.mist { border-radius: 50%; background: radial-gradient(circle, rgba(236, 248, 255, .95), rgba(236, 248, 255, 0) 68%); animation: oh-mist 1.2s ease-out both; }
@keyframes oh-mist { 0% { opacity: 0; transform: translate(0, 0) scale(.5); } 25% { opacity: .9; } 100% { opacity: 0; transform: translate(var(--px), var(--py)) scale(1.7); } }
.oh-fxp.steamp { border-radius: 50%; background: radial-gradient(circle, rgba(255, 255, 255, .9), rgba(255, 255, 255, 0) 70%); animation: oh-steamp 1.4s ease-out both; }
@keyframes oh-steamp { 0% { opacity: 0; transform: translate(0, 0) scale(.5); } 30% { opacity: .85; } 100% { opacity: 0; transform: translate(var(--px), var(--py)) scale(1.5); } }
.oh-fxp.flame { background: #FFB547; box-shadow: 0 0 6px 2px rgba(255, 170, 60, .7); animation: oh-flame .18s steps(2) infinite alternate; }
@keyframes oh-flame { to { transform: scaleY(1.4); background: #FF8A3D; } }
.oh-fxp.note8 { font-size: 13px; color: #5B8FD6; text-shadow: 0 1px 0 #FFFFFF; animation: oh-steamp 1.6s ease-out both; }
.oh-doorfx { position: absolute; pointer-events: none; overflow: visible; }
.oh-doorfx .inside { position: absolute; border-radius: 2px; background: linear-gradient(180deg, #F4FBFF, #CFE6F7); box-shadow: 0 0 18px 6px rgba(210, 236, 255, .75); opacity: 0; animation: oh-inon .3s ease-out .08s forwards; }
.oh-doorfx.warm .inside { background: linear-gradient(180deg, #FBF7F0, #E7EDF5); box-shadow: 0 0 12px 4px rgba(255, 248, 230, .6); }
@keyframes oh-inon { to { opacity: 1; } }
.oh-doorfx .leaf { position: absolute; top: 0; height: 100%; background-repeat: no-repeat; image-rendering: pixelated; animation: oh-leafopen .34s cubic-bezier(.3, .8, .4, 1) forwards; }
.oh-doorfx .leaf.l { transform-origin: 0 50%; }
.oh-doorfx .leaf.r { transform-origin: 100% 50%; }
@keyframes oh-leafopen { to { transform: scaleX(.16); filter: brightness(1.08); } }
.oh-doorfx.closing .leaf { animation: oh-leafclose .26s ease-in forwards; }
.oh-doorfx.closing .inside { animation: oh-inoff .26s ease-in forwards; }
@keyframes oh-leafclose { from { transform: scaleX(.16); } to { transform: scaleX(1); } }
@keyframes oh-inoff { from { opacity: 1; } to { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .oh-item.oh-sway img, .oh-item.oh-squash img, .oh-item.oh-tug img, .oh-item.oh-tapb img, .oh-item.oh-shake img, .oh-item.oh-bobm img, .oh-item.oh-prop.wig img, .oh-fxp, .oh-doorfx .leaf, .oh-doorfx .inside { animation: none !important; } }

/* 选中家具的工具条: 层级 opens a second row */
.oh-seltools { flex-wrap: wrap; justify-content: center; width: max-content; max-width: min(300px, 92vw); }
.oh-seltools .oh-layrow { display: none; flex: 0 0 100%; gap: 4px; justify-content: center; }
.oh-seltools.lay .oh-layrow { display: flex; }
#companion-body .oh-seltools button.on { background: var(--oh-accent); color: var(--oh-accent-ink); }
/* 墙纸 / 地板: the upper or the lower half of a room that has a 隔墙 */
.oh-half { grid-column: 1 / -1; display: flex; gap: 6px; padding: 0 0 2px; }
#companion-body .oh-dock-row .oh-half button { width: auto; height: 36px; min-width: 88px; flex: none; flex-direction: row; justify-content: center; gap: 0; }
#companion-body .oh-dock-row .oh-half button.on { background: var(--oh-accent); color: var(--oh-accent-ink); }
/* dialogs: frosted glass; one that is already open changes its content without popping up again */
.oh-sheet.show { animation: oh-popin .34s cubic-bezier(.34, 1.4, .64, 1) both; transition: none; }
.oh-sheet.show.stay { animation: none; }
@keyframes oh-popin { 0% { opacity: 0; transform: translate(-50%, -50%) scale(.86); } 60% { opacity: 1; transform: translate(-50%, -50%) scale(1.03); } 100% { opacity: 1; transform: translate(-50%, -50%) scale(1); } }
.oh-sheet button.tapped { animation: oh-tappick .28s cubic-bezier(.34, 1.6, .64, 1); }
@keyframes oh-tappick { 0% { transform: scale(.94); } 100% { transform: scale(1); } }
.oh-gi, .oh-inv .gi, .oh-dock-row .invc .gi { object-fit: contain; }
@media (prefers-reduced-motion: reduce) { .oh-sheet.show, .oh-sheet button.tapped { animation: none; } }

/* ═══ 毛玻璃圆角 (v5, design _handoff/home-v5/design.md 二.8): the chrome of the whole 线下 (the home, the town, the city map, the shops, a character's home) is frosted glass:
   a translucent --gl, a 1px light edge, a soft shadow, 18px blur and 20-22px corners. No white boards, no thick dark outlines, no square corners; time, dates and counts are in the body font
   (no Silkscreen). Only the style changes - the same buttons in the same places. Everything is scoped by `#companion-body .oh-root` so it wins over the older rules above. ═══ */
.oh-root { --gl: rgba(255, 255, 255, .66); --gl2: rgba(255, 255, 255, .74); --gle: rgba(255, 255, 255, .78); --gls: 0 18px 40px rgba(40, 60, 90, .22); --gi: #2E3A4F; --gi2: #5E6C82; --acc: rgba(70, 120, 200, .96); --acc-ink: #FFFFFF; }
.oh-root.night { --gl: rgba(34, 43, 59, .74); --gl2: rgba(52, 64, 86, .78); --gle: rgba(255, 255, 255, .16); --gls: 0 18px 40px rgba(0, 0, 0, .4); --gi: #E8EEF6; --gi2: #A9B6C9; --acc: rgba(110, 160, 232, .96); --acc-ink: #0E131C; }
:root[data-theme="dark"] .oh-root { --gl: rgba(34, 43, 59, .74); --gl2: rgba(52, 64, 86, .78); --gle: rgba(255, 255, 255, .16); --gls: 0 18px 40px rgba(0, 0, 0, .4); --gi: #E8EEF6; --gi2: #A9B6C9; --acc: rgba(110, 160, 232, .96); --acc-ink: #0E131C; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .oh-root { --gl: rgba(34, 43, 59, .74); --gl2: rgba(52, 64, 86, .78); --gle: rgba(255, 255, 255, .16); --gls: 0 18px 40px rgba(0, 0, 0, .4); --gi: #E8EEF6; --gi2: #A9B6C9; --acc: rgba(110, 160, 232, .96); --acc-ink: #0E131C; }
}
/* the floating pieces: status bars, buttons, the 他此刻 card, the hint, the tools above the drawer and over a selected piece, the mode card of the map */
#companion-body .oh-root .oh-status, #companion-body .oh-root .oh-pxbtn, #companion-body .oh-root .oh-who, #companion-body .oh-root .oh-hint, #companion-body .oh-root .oh-seltools button, #companion-body .oh-root .ot-mode {
  background: var(--gl); color: var(--gi); border: 1px solid var(--gle); box-shadow: 0 8px 20px rgba(40, 60, 90, .16); backdrop-filter: blur(18px) saturate(1.4); -webkit-backdrop-filter: blur(18px) saturate(1.4); border-radius: 22px;
}
#companion-body .oh-root .oh-status { padding: 0 16px; letter-spacing: 0; white-space: normal; }
#companion-body .oh-root .oh-status b, #companion-body .oh-root .oh-status * { font-family: inherit; font-weight: 600; font-size: 13px; color: var(--gi); letter-spacing: 0; }
#companion-body .oh-root .oh-pxbtn { min-width: 44px; }
#companion-body .oh-root .oh-pxbtn:active { transform: scale(.96); box-shadow: 0 4px 10px rgba(40, 60, 90, .14); }
#companion-body .oh-root .oh-pxbtn.on { background: var(--acc); color: var(--acc-ink); }
#companion-body .oh-root .oh-pxbtn.oh-sm, #companion-body .oh-root .oh-seltools button { border-radius: 18px; box-shadow: 0 6px 16px rgba(40, 60, 90, .16); }
#companion-body .oh-root .oh-seltools button:active { transform: scale(.96); box-shadow: none; }
#companion-body .oh-root .oh-who { padding: 10px 14px; box-shadow: 0 10px 26px rgba(40, 60, 90, .18); backdrop-filter: blur(20px) saturate(1.4); -webkit-backdrop-filter: blur(20px) saturate(1.4); }
#companion-body .oh-root .oh-who b { color: var(--gi); } #companion-body .oh-root .oh-who span { color: var(--gi2); }
#companion-body .oh-root .oh-av { border: 0; border-radius: 50%; box-shadow: none; }
#companion-body .oh-root .oh-who .oh-st { font-family: inherit; font-size: 11px; color: var(--gi2); }
#companion-body .oh-root .oh-who .oh-st i { border-radius: 50%; }
#companion-body .oh-root .oh-hint { border-radius: 16px; padding: 5px 12px; box-shadow: 0 6px 16px rgba(40, 60, 90, .14); backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px); }
#companion-body .oh-root .oh-toast { border-radius: 18px; background: rgba(46, 58, 79, .8); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); padding: 9px 16px; }
#companion-body .oh-root .ot-mode { border-radius: 20px; }
#companion-body .oh-root .ot-mode small { color: var(--gi2); }
/* the 装修 drawer */
#companion-body .oh-root .oh-dock { background: var(--gl); border-top: 1px solid var(--gle); box-shadow: 0 -10px 30px rgba(40, 60, 90, .16); border-radius: 24px 24px 0 0; backdrop-filter: blur(22px) saturate(1.4); -webkit-backdrop-filter: blur(22px) saturate(1.4); transition: transform .28s cubic-bezier(.34, 1.3, .64, 1); }
#companion-body .oh-root .oh-grip span { border-radius: 2px; background: var(--gi2); opacity: .5; }
#companion-body .oh-root .oh-cats button, #companion-body .oh-root .oh-dock-row button { border: 0; border-radius: 16px; box-shadow: none; background: var(--gl2); color: var(--gi); }
#companion-body .oh-root .oh-cats button.on, #companion-body .oh-root .oh-dock-row button.pick, #companion-body .oh-root .oh-dock-row .look.on, #companion-body .oh-root .oh-dock-row .oh-half button.on { background: var(--acc); color: var(--acc-ink); }
#companion-body .oh-root .oh-dock-row .cnt { font-family: inherit; font-weight: 600; border-radius: 7px; background: var(--acc); color: var(--acc-ink); }
#companion-body .oh-root .oh-dock-row .look img { border: 0; border-radius: 8px; }
#companion-body .oh-root .oh-dock-empty, #companion-body .oh-root .oh-invc span, #companion-body .oh-root .oh-dock-row .invc span { color: var(--gi2); }
/* dialogs: the dialog itself is glass already (.oh-sheet.glass); its parts and buttons are glass too */
#companion-body .oh-root .oh-sheet { border: 1px solid var(--gle); border-radius: 26px; box-shadow: var(--gls); }
#companion-body .oh-root .oh-sheet .oh-close { border-radius: 50%; }
#companion-body .oh-root .oh-opt, #companion-body .oh-root .oh-opts .oh-opt { border: 0; border-radius: 18px; box-shadow: none; background: var(--gl2); color: var(--gi); }
#companion-body .oh-root .oh-opt:active { transform: scale(.98); box-shadow: none; }
#companion-body .oh-root .oh-opt span, #companion-body .oh-root .oh-opts .oh-opt .oh-go { color: var(--gi2); font-family: inherit; }
#companion-body .oh-root .oh-opts .oh-opt .oh-icw { border: 0; border-radius: 14px; }
#companion-body .oh-root .oh-opts .oh-opt em { border: 0; border-radius: 8px; }
#companion-body .oh-root .oh-primary, #companion-body .oh-root .oh-act { border: 0; border-radius: 24px; background: var(--acc); color: var(--acc-ink); box-shadow: 0 6px 16px rgba(70, 120, 200, .3); font-weight: 600; }
#companion-body .oh-root .oh-sheetbtns .oh-pxbtn { border: 0; border-radius: 24px; box-shadow: none; min-height: 46px; font-size: 14px; background: var(--gl2); color: var(--gi); backdrop-filter: none; -webkit-backdrop-filter: none; }
#companion-body .oh-root .oh-sheetbtns .oh-pxbtn:first-child { background: var(--acc); color: var(--acc-ink); box-shadow: 0 6px 16px rgba(70, 120, 200, .3); }
#companion-body .oh-root .oh-sheetbtns .oh-pxbtn.g { background: var(--gl2); color: var(--gi); box-shadow: none; }
#companion-body .oh-root .oh-outfits button, #companion-body .oh-root .oh-setopt button, #companion-body .oh-root .ot-buyit, #companion-body .oh-root .ot-cat, #companion-body .oh-root .oh-lk-grid button, #companion-body .oh-root .oh-lrow {
  border: 0; border-radius: 14px; box-shadow: none; background: var(--gl2); color: var(--gi);
}
#companion-body .oh-root .oh-outfits button.on, #companion-body .oh-root .oh-setopt button.on, #companion-body .oh-root .ot-buyit.on, #companion-body .oh-root .oh-lk-grid button.on { background: var(--acc); color: var(--acc-ink); box-shadow: none; }
#companion-body .oh-root .oh-lk-grid button img { border-radius: 8px; }
#companion-body .oh-root .oh-lk-seg { border-radius: 14px; }
#companion-body .oh-root .oh-lk-seg button { border-radius: 11px; }
#companion-body .oh-root .oh-lk-seg button.on { background: var(--acc); color: var(--acc-ink); }
.oh-root .oh-stile, .oh-root .oh-hero, .oh-root .oh-letter, .oh-root .oh-rows, .oh-root .oh-inv, .oh-root .oh-pcard, .oh-root .oh-pchip, .oh-root .oh-pill, .oh-root .oh-paper { border: 0; box-shadow: none; }
.oh-root .oh-stile { border-radius: 16px; }
.oh-root .oh-hero { border-radius: 20px; }
.oh-root .oh-letter { border-radius: 18px; background: var(--gl2); box-shadow: 0 4px 14px rgba(40, 60, 90, .08); }
.oh-root .oh-rows, .oh-root .oh-inv, .oh-root .oh-pcard { border-radius: 14px; background: var(--gl2); }
.oh-root .oh-pchip, .oh-root .oh-pill { border-radius: 9px; }
.oh-root .oh-paper { border-radius: 14px; box-shadow: 0 4px 14px rgba(40, 60, 90, .1); }
.oh-root .oh-setsec { border-top: 1px solid rgba(46, 58, 79, .12); }
.oh-root .oh-cal-row .d { font-family: inherit; font-weight: 600; }
.oh-root .ot-av, .oh-root .oh-lav { border: 0; border-radius: 50%; }
.oh-root .ot-hit .nm { border: 1px solid var(--gle); border-radius: 9px; background: var(--gl); color: var(--gi); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); }
.oh-root .ot-edit-grid .it, .oh-root .ot-buyit .gi { border: 0; border-radius: 10px; }

/* ── 在店里见面 (见面 v5): the shop fills the screen, one frosted-glass box at the bottom shows one sentence at a time (js/apps/offline-date-scene.js) ── */
.oh-root .od-vn { position: absolute; inset: 0; z-index: 6; pointer-events: none; display: flex; flex-direction: column; justify-content: space-between; }
.oh-root .od-vn[hidden] { display: none; }
.oh-root .od-vn::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 320px; background: linear-gradient(180deg, transparent, rgba(30, 40, 60, .3)); z-index: -1; }
.oh-root .od-vn-top { display: flex; justify-content: space-between; align-items: center; gap: 8px; margin: calc(58px + env(safe-area-inset-top)) 14px 0; }
.oh-root .od-who { display: inline-flex; align-items: center; gap: 6px; height: 34px; padding: 0 12px 0 4px; border-radius: 999px; background: var(--gl2); border: 1px solid var(--gle); color: var(--gi); font-size: 13px; backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px); box-shadow: 0 4px 12px rgba(40, 60, 90, .14); pointer-events: auto; }
.oh-root .od-av { display: inline-grid; place-items: center; width: 26px; height: 26px; border-radius: 50%; color: #fff; font-size: 11px; font-style: normal; }
.oh-root .od-who small { color: var(--gi2); font-size: 11px; }
.oh-root .od-top-btns { display: inline-flex; gap: 6px; }
.oh-root .od-top-btn { min-height: 34px; min-width: 44px; padding: 0 12px; border-radius: 999px; background: var(--gl2); border: 1px solid var(--gle); color: var(--gi); font-size: 13px; backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px); box-shadow: 0 4px 12px rgba(40, 60, 90, .14); pointer-events: auto; cursor: pointer; }
.oh-root .od-vn-bottom { display: flex; flex-direction: column; gap: 8px; padding: 0 14px calc(14px + env(safe-area-inset-bottom)); }
.oh-root .od-vnbox { position: relative; box-sizing: border-box; width: 100%; height: 136px; overflow-y: auto; scrollbar-width: none; margin-top: 18px; padding: 22px 20px 26px; border-radius: 22px; background: var(--gl2); color: var(--gi); border: 1px solid var(--gle); font-size: 16px; line-height: 1.65; cursor: pointer; pointer-events: auto; box-shadow: 0 12px 30px rgba(30, 45, 70, .22), inset 0 1px 0 rgba(255, 255, 255, .6); backdrop-filter: blur(22px) saturate(1.5); -webkit-backdrop-filter: blur(22px) saturate(1.5); }
.oh-root .od-vntag { position: absolute; left: 16px; top: -14px; padding: 3px 14px; border-radius: 999px; background: var(--gl); color: var(--gi); border: 1px solid var(--gle); font-size: 13px; font-weight: 500; line-height: 1.5; box-shadow: 0 4px 12px rgba(30, 45, 70, .16); backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px); }
.oh-root .od-vntag:empty { display: none; }
.oh-root .od-vnbox.me .od-vntag { background: rgba(91, 143, 214, .85); color: #fff; border-color: rgba(255, 255, 255, .5); }
.oh-root .od-vnbox.n .od-vntx { color: var(--gi2); font-style: italic; font-size: 14.5px; }
.oh-root .od-vnnext { display: none; position: absolute; right: 16px; bottom: 10px; width: 0; height: 0; border: 7px solid transparent; border-top: 10px solid var(--gi2); border-bottom: 0; animation: od-bob 1s steps(2) infinite; }
.oh-root .od-vnbox.more .od-vnnext { display: block; }
@keyframes od-bob { 50% { transform: translateY(3px); } }
.oh-root .od-dots { display: inline-flex; gap: 5px; align-items: center; height: 26px; }
.oh-root .od-dots i { width: 7px; height: 7px; border-radius: 50%; background: var(--gi2); opacity: .4; animation: od-dot 1.2s infinite; }
.oh-root .od-dots i:nth-child(2) { animation-delay: .2s; }
.oh-root .od-dots i:nth-child(3) { animation-delay: .4s; }
@keyframes od-dot { 50% { opacity: 1; } }
.oh-root .od-chips { display: flex; flex-direction: column; gap: 8px; }
.oh-root .od-chips:empty { display: none; }
.oh-root .od-chips button { align-self: flex-start; max-width: 100%; min-height: 40px; padding: 0 18px; border-radius: 999px; background: var(--gl); color: var(--gi); border: 1px solid var(--gle); font-size: 14.5px; text-align: left; box-shadow: 0 4px 14px rgba(30, 45, 70, .14); backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px); pointer-events: auto; cursor: pointer; }
.oh-root .od-chips button { height: auto; padding-top: 8px; padding-bottom: 8px; line-height: 1.4; white-space: normal; overflow-wrap: anywhere; }
.oh-root .od-chips button.dir { display: inline-flex; align-items: flex-start; gap: 6px; }
.oh-root .od-chips button.dir svg { flex: none; width: 14px; height: 14px; margin-top: 3px; }
.oh-root .od-in { display: flex; gap: 8px; }
.oh-root .od-in input { flex: 1; min-width: 0; min-height: 44px; padding: 0 18px; border-radius: 999px; background: var(--gl2); color: var(--gi); border: 1px solid var(--gle); font-size: 16px; box-shadow: 0 4px 14px rgba(30, 45, 70, .14); backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px); pointer-events: auto; }
.oh-root .od-send { width: 44px; min-width: 44px; height: 44px; border-radius: 50%; background: var(--gl2); color: var(--gi); border: 1px solid var(--gle); font-size: 18px; pointer-events: auto; cursor: pointer; }
.oh-root .od-send:disabled { display: none; }
.oh-root .od-vn.busy .od-chips { opacity: .5; }
/* while a meeting is on, the shop behind it is only a picture */
.ot-root.talk .ot-sc, .ot-root.talk .ot-hits, .ot-root.talk .ot-acts { pointer-events: none; }
.ot-root.talk .ot-acts { display: none; }
@media (prefers-reduced-motion: reduce) { .oh-root .od-vnnext, .oh-root .od-dots i { animation: none; } }
.oh-root .od-vnbox::-webkit-scrollbar { display: none; }

/* ── 约会 from 线下 (js/apps/offline-date-go.js): the list, the invitation, the reminder ── */
.oh-root .dg-pill { position: absolute; left: 50%; top: calc(62px + env(safe-area-inset-top)); transform: translateX(-50%); z-index: 31; display: flex; align-items: center; gap: 8px; max-width: calc(100% - 28px); padding: 6px 6px 6px 12px; border-radius: 999px; background: var(--gl2); color: var(--gi); border: 1px solid var(--gle); box-shadow: 0 8px 20px rgba(40, 60, 90, .18); font: inherit; font-size: 12px; white-space: nowrap; cursor: pointer; }
.oh-root .dg-pill[hidden] { display: none; }
.oh-root:has(.oh-sheet.show) .dg-pill { display: none; }   /* under any dialog the reminder is gone at once, and back when it closes */
.oh-root .dg-pill span { overflow: hidden; text-overflow: ellipsis; }
.oh-root .dg-pill i { flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--acc); }
.oh-root .dg-pill.w i { background: var(--gi2); }
.oh-root .dg-pill b { flex: none; padding: 4px 10px; border-radius: 999px; background: var(--acc); color: var(--acc-ink); font-weight: 600; }
.oh-root .od-list { display: flex; flex-direction: column; gap: 8px; max-height: 46vh; overflow-y: auto; scrollbar-width: none; margin: 8px 0; }
.oh-root .od-list::-webkit-scrollbar, .oh-root .od-days::-webkit-scrollbar, .oh-root .od-places::-webkit-scrollbar, .oh-root .od-pick::-webkit-scrollbar { display: none; }
.oh-root .od-card { display: grid; grid-template-columns: 34px 1fr auto; gap: 4px 10px; align-items: center; padding: 10px 12px; border-radius: 16px; background: var(--gl2); border: 1px solid var(--gle); color: var(--gi); }
.oh-root .od-av2 { display: inline-grid; place-items: center; width: 30px; height: 30px; border-radius: 50%; font-size: 12px; font-style: normal; }
.oh-root .od-nm { font-size: 14px; font-weight: 600; min-width: 0; }
.oh-root .dg-chip { display: block; margin-top: 1px; font-size: 11px; font-weight: 400; color: var(--gi2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.oh-root .od-st { justify-self: end; padding: 2px 10px; border-radius: 999px; font-size: 11px; border: 1px solid var(--gle); color: var(--gi); white-space: nowrap; }
.oh-root .od-st.ok, .oh-root .od-st.soon { border-color: var(--acc); }
.oh-root .od-st.soon { font-weight: 600; }
.oh-root .od-st.bad { border-style: dashed; }
.oh-root .od-tx { grid-column: 2 / 4; font-size: 12px; color: var(--gi2); }
.oh-root .od-acts { grid-column: 1 / 4; display: flex; gap: 8px; justify-content: flex-end; }
.oh-root .od-act { min-height: 36px; min-width: 64px; padding: 0 16px; border-radius: 999px; border: 1px solid var(--gle); background: var(--acc); color: var(--acc-ink); font-size: 13px; cursor: pointer; }
.oh-root .od-act.g { background: var(--gl); color: var(--gi); }
.oh-root .dg-empty { padding: 16px 8px; text-align: center; font-size: 13px; color: var(--gi2); }
.oh-root .od-lbtns { margin-top: 6px; }
/* 约一个人 (the invitation): a letter that fills in, three steps under it, and an envelope when it goes (js/apps/offline-date-go.js) */
.oh-root .oh-sheet:has(.od-ivcard) { max-width: 350px; }
.oh-root .oh-sheet:has(.od-ivcard) [data-oh="sheetBody"] { padding-top: 34px; }
.oh-root .oh-sheet:has(.od-ivcard)::before { content: '约 会'; position: absolute; left: 20px; top: 16px; font-size: 14px; letter-spacing: 3px; color: var(--gi2); z-index: 1; }
.oh-root .oh-sheet:has(.od-ivcard) .oh-close { z-index: 6; }
.oh-root .od-ivcard { position: relative; overflow: hidden; margin: 6px 0 4px; padding: 14px 22px 12px; border-radius: 18px; color: var(--gi); background: linear-gradient(180deg, rgba(140, 185, 240, .26), rgba(255, 255, 255, 0) 60%), var(--gl); border: 1px solid var(--gle); box-shadow: 0 8px 22px rgba(40, 60, 90, .14); }
.oh-root .od-ivcard::before { content: ''; position: absolute; inset: 6px; border: 1.5px dashed rgba(91, 143, 214, .4); border-radius: 13px; pointer-events: none; }
.oh-root .od-ivt { text-align: center; font-size: 12px; letter-spacing: .3em; margin-bottom: 6px; color: var(--gi2); }
.oh-root .od-ivrow { display: flex; align-items: center; gap: 10px; min-height: 34px; font-size: 14px; border-bottom: 1px solid rgba(128, 144, 168, .16); }
.oh-root .od-ivrow:last-child { border-bottom: 0; }
.oh-root .od-ivk { flex: none; width: 30px; color: var(--gi2); font-size: 12px; }
.oh-root .od-ivv { flex: 1; display: flex; align-items: center; gap: 8px; min-width: 0; }
.oh-root .od-ivv > span:not(.od-stamp) { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.oh-root .od-ph { color: var(--gi2); letter-spacing: .2em; }
.oh-root .od-ivv img { height: 22px; image-rendering: pixelated; }
.oh-root .od-ivv.pop > * { animation: od-pop .45s cubic-bezier(.34, 1.6, .64, 1) both; }
@keyframes od-pop { 0% { opacity: 0; transform: scale(.4); } 100% { opacity: 1; transform: none; } }
.oh-root .od-stamp { margin-left: auto; flex: none; margin-right: 8px; white-space: nowrap; letter-spacing: 0; display: inline-flex; flex-direction: column; align-items: center; justify-content: center; width: 46px; height: 46px; margin-top: -6px; margin-bottom: -6px; border-radius: 50%; border: 2px solid #E8879C; color: #E8879C; font-size: 10px; line-height: 1.2; font-weight: 600; transform: rotate(-12deg); background: rgba(255, 240, 244, .6); animation: od-stamp-in .4s cubic-bezier(.3, 1.6, .5, 1) both; }
.oh-root .od-stamp b { font-size: 12px; }
@keyframes od-stamp-in { 0% { opacity: 0; transform: rotate(-12deg) scale(1.9); } 60% { opacity: 1; transform: rotate(-12deg) scale(.92); } 100% { transform: rotate(-12deg) scale(1); } }
.oh-root .od-av2 { display: inline-grid; place-items: center; flex: none; width: 24px; height: 24px; border-radius: 50%; overflow: hidden; color: #fff; font-size: 12px; font-style: normal; }
.oh-root .od-card .od-av2 { width: 30px; height: 30px; }
.oh-root .od-av2.big { width: 46px; height: 46px; font-size: 18px; box-shadow: 0 6px 14px rgba(40, 60, 90, .2); }
.oh-root .oh-faceimg { display: block; width: 100%; height: 100%; object-fit: cover; border-radius: inherit; }
.oh-root .oh-av, .oh-root .oh-lav, .oh-root .ot-av, .oh-root .od-av { overflow: hidden; }
.oh-root .oh-stile.oh-av2 { overflow: hidden; }
.oh-root [data-od-step], .oh-root .od-ivcard { flex: none; }
.oh-root .od-step { margin: 14px 0 12px; animation: od-in .32s ease-out both; }
@keyframes od-in { 0% { opacity: 0; transform: translateX(18px); } 100% { opacity: 1; transform: none; } }
.oh-root .od-h { font-size: 15px; font-weight: 600; color: var(--gi); }
.oh-root .od-s { margin: 2px 0 4px; font-size: 12px; color: var(--gi2); }
.oh-root .od-note { margin-top: 8px; padding: 7px 10px; border-radius: 12px; font-size: 12px; color: var(--gi2); background: var(--gl2); }
.oh-root .od-clash[hidden] { display: none; }
.oh-root .od-pick, .oh-root .od-days, .oh-root .od-places, .oh-root .od-tabs { flex: none; display: flex; gap: 10px; overflow-x: auto; scrollbar-width: none; touch-action: pan-x; }
.oh-root .od-pick::-webkit-scrollbar, .oh-root .od-days::-webkit-scrollbar, .oh-root .od-places::-webkit-scrollbar, .oh-root .od-tabs::-webkit-scrollbar { display: none; }
.oh-root .od-pick { margin-top: 6px; padding: 8px 4px 10px; }
.oh-root .od-pick > * { flex: none; }
#companion-body .oh-root .od-pick button { width: 92px; display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 12px 6px 10px; border: 0; border-radius: 18px; background: var(--gl2); color: var(--gi); font: inherit; cursor: pointer; transition: transform .2s cubic-bezier(.34, 1.6, .64, 1); }
#companion-body .oh-root .od-pick button b { font-size: 13px; }
#companion-body .oh-root .od-pick button i { font-style: normal; font-size: 11px; line-height: 1.3; text-align: center; color: var(--gi2); }
#companion-body .oh-root .od-pick button:disabled { opacity: .5; cursor: default; }
#companion-body .oh-root .od-pick button.on, #companion-body .oh-root .dg-place.on { background: var(--gl); box-shadow: 0 0 0 2px rgba(91, 143, 214, .8); transform: translateY(-3px); }
.oh-root .od-days { margin-top: 10px; padding: 2px 2px 8px; scroll-snap-type: x mandatory; }
.oh-root .od-day { flex: none; width: 118px; scroll-snap-align: start; padding: 10px 8px 8px; border-radius: 18px; background: var(--gl2); color: var(--gi); }
.oh-root .od-day .dl { font-size: 12px; color: var(--gi2); text-align: left; }
.oh-root .od-day .dn { margin: 2px 0 6px; font-size: 30px; font-weight: 600; line-height: 1.1; text-align: left; color: var(--gi); }
.oh-root .od-day.today .dn { color: #5B8FD6; }
#companion-body .oh-root .od-slot { width: 100%; min-height: 32px; display: flex; align-items: center; gap: 5px; margin-top: 5px; padding: 6px 6px; border: 0; border-radius: 12px; background: var(--gl); color: var(--gi); font: inherit; font-size: 12px; text-align: left; cursor: pointer; transition: transform .18s; }
#companion-body .oh-root .od-slot:active { transform: scale(.95); }
#companion-body .oh-root .od-slot span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#companion-body .oh-root .od-slot i { width: 12px; height: 12px; flex: none; border-radius: 50%; }
#companion-body .oh-root .od-slot i.s0 { background: #FFD36B; box-shadow: 0 0 0 2px rgba(255, 211, 107, .35); }
#companion-body .oh-root .od-slot i.s1 { background: linear-gradient(135deg, #FFB86B 50%, #F7D9A8 50%); }
#companion-body .oh-root .od-slot i.s2 { background: transparent; box-shadow: inset -4px 1px 0 0 #8FA7D6; }
#companion-body .oh-root .od-slot.maybe { background: rgba(255, 241, 201, .85); color: #7A6418; }
#companion-body .oh-root .od-slot:disabled { background: transparent; color: var(--gi2); opacity: .75; text-decoration: line-through; cursor: default; }
#companion-body .oh-root .od-slot.on { background: #4577BD; color: #fff; }
#companion-body .oh-root .od-slot.on i.s2 { box-shadow: inset -4px 1px 0 0 #fff; }
.oh-root .od-tabs { gap: 6px; margin-top: 10px; }
#companion-body .oh-root .od-tabs button { flex: none; min-height: 32px; padding: 6px 12px; border: 0; border-radius: 14px; background: var(--gl2); color: var(--gi); font: inherit; font-size: 12px; cursor: pointer; }
#companion-body .oh-root .od-tabs button.on { background: #4577BD; color: #fff; }
.oh-root .od-places { margin-top: 10px; padding: 2px 2px 8px; scroll-snap-type: x mandatory; }
#companion-body .oh-root .dg-place { flex: none; width: 132px; scroll-snap-align: start; display: flex; flex-direction: column; align-items: center; gap: 3px; padding: 10px 8px; border: 0; border-radius: 18px; background: var(--gl2); color: var(--gi); font: inherit; cursor: pointer; transition: transform .2s cubic-bezier(.34, 1.6, .64, 1); }
#companion-body .oh-root .dg-place:disabled { opacity: .5; cursor: default; }
.oh-root .od-pic { display: flex; align-items: flex-end; justify-content: center; width: 100%; height: 84px; border-radius: 12px; background: radial-gradient(circle at 50% 85%, rgba(170, 205, 240, .55), rgba(255, 255, 255, 0) 70%); }
.oh-root .od-pic img { max-width: 100%; max-height: 80px; image-rendering: pixelated; }
#companion-body .oh-root .dg-place b { font-size: 13px; }
#companion-body .oh-root .dg-place i { font-style: normal; font-size: 11px; line-height: 1.35; color: var(--gi2); }
/* sending: the card folds into an envelope, is sealed and flies off */
.oh-root .od-env { position: absolute; left: 50%; top: 50%; width: 230px; height: 140px; margin: -70px 0 0 -115px; z-index: 5; pointer-events: none; opacity: 0; }
.oh-root .od-env .back { position: absolute; inset: 0; border-radius: 12px; background: #EAF2FB; box-shadow: 0 14px 30px rgba(40, 60, 90, .25); }
.oh-root .od-env .front { position: absolute; inset: 0; border-radius: 12px; z-index: 3; background: linear-gradient(to top right, #F7FAFE 49.6%, transparent 50%) left / 50% 100% no-repeat, linear-gradient(to top left, #F7FAFE 49.6%, transparent 50%) right / 50% 100% no-repeat; }
.oh-root .od-env .flap { position: absolute; left: 0; right: 0; top: 0; height: 78px; z-index: 4; transform-origin: 50% 0; transform: rotateX(180deg); background: linear-gradient(to bottom right, #DDE9F7 49.6%, transparent 50%) left / 50% 100% no-repeat, linear-gradient(to bottom left, #DDE9F7 49.6%, transparent 50%) right / 50% 100% no-repeat; }
.oh-root .od-env .seal { position: absolute; left: 50%; top: 62px; width: 26px; height: 26px; margin-left: -13px; border-radius: 50%; background: #E8879C; box-shadow: inset -3px -3px 0 rgba(0, 0, 0, .12); z-index: 5; transform: scale(0); }
#companion-body .oh-root .oh-sheet.sending { overflow: visible; background: transparent; border-color: transparent; box-shadow: none; backdrop-filter: none; -webkit-backdrop-filter: none; }
.oh-root .oh-sheet.sending [data-od-step], .oh-root .oh-sheet.sending .oh-sheetbtns, .oh-root .oh-sheet.sending .oh-close { opacity: 0 !important; animation: none !important; transition: opacity .2s; pointer-events: none; }
.oh-root .oh-sheet.sending::before { opacity: 0; }
.oh-root .oh-sheet.sending .od-ivcard { animation: od-card-out .7s cubic-bezier(.5, 0, .6, 1) forwards; }
@keyframes od-card-out { 0% { transform: none; } 40% { transform: translateY(40px) scale(.62); } 100% { transform: translateY(64px) scale(.5); opacity: 0; } }
.oh-root .oh-sheet.sending .od-env { animation: od-env-show .3s ease-out .35s forwards, od-env-fly .7s cubic-bezier(.5, -.4, .7, 1) 1.5s forwards; }
.oh-root .oh-sheet.sending .od-env .flap { animation: od-flap .3s ease-in .85s forwards; }
.oh-root .oh-sheet.sending .od-env .seal { animation: od-seal .35s cubic-bezier(.3, 1.8, .5, 1) 1.15s forwards; }
@keyframes od-env-show { to { opacity: 1; } } @keyframes od-flap { to { transform: rotateX(0); } } @keyframes od-seal { to { transform: scale(1); } }
@keyframes od-env-fly { to { opacity: 0; transform: translate(160px, -320px) rotate(18deg) scale(.5); } }
@media (prefers-reduced-motion: reduce) {
  .oh-root .od-step, .oh-root .od-ivv.pop > *, .oh-root .od-stamp { animation: none; }
  .oh-root .od-pick button, .oh-root .dg-place, .oh-root .od-slot { transition: none; }
}
.oh-root .od-paper.ot-early, .oh-root .ot-early { margin-top: 8px; }

/* the close button of the invitation: a 32px round button on a light ground */
#companion-body .oh-root .oh-sheet:has(.od-ivcard) .oh-close { top: 10px; right: 12px; width: 32px; height: 32px; min-width: 32px; min-height: 32px; padding: 0; border-radius: 50%; background: var(--gl2); color: var(--gi); font-size: 18px; line-height: 32px; display: grid; place-items: center; box-shadow: 0 2px 8px rgba(40, 60, 90, .12); }

/* ── the fridge, the wardrobe, the cork board and the mailbox open as the thing itself (design: _handoff/offline-ui-align, B 款) ── */
.oh-root { --ib-fridge: linear-gradient(180deg, rgba(214, 233, 249, .95), rgba(184, 214, 240, .92)); --ib-closet: linear-gradient(180deg, rgba(248, 250, 253, .96), rgba(224, 232, 243, .93)); --ib-mail: linear-gradient(180deg, rgba(220, 232, 246, .95), rgba(196, 214, 236, .92)); --ib-board: linear-gradient(180deg, rgba(255, 255, 255, .95), rgba(226, 236, 246, .92)); --ib-door: rgba(190, 216, 240, .95); --ib-line: rgba(255, 255, 255, .95); --ib-edge: rgba(255, 255, 255, .85); --ib-ink: #2E3A4F; --ib-ink2: #55667E; }
.oh-root.night { --ib-fridge: linear-gradient(180deg, rgba(48, 66, 92, .96), rgba(34, 48, 70, .95)); --ib-closet: linear-gradient(180deg, rgba(58, 68, 88, .96), rgba(40, 50, 68, .95)); --ib-mail: linear-gradient(180deg, rgba(46, 60, 84, .96), rgba(34, 46, 66, .95)); --ib-board: linear-gradient(180deg, rgba(52, 62, 82, .96), rgba(38, 48, 68, .95)); --ib-door: rgba(70, 92, 124, .95); --ib-line: rgba(255, 255, 255, .34); --ib-edge: rgba(255, 255, 255, .22); --ib-ink: #E8EEF6; --ib-ink2: #A9B6C9; }
:root[data-theme="dark"] .oh-root { --ib-fridge: linear-gradient(180deg, rgba(48, 66, 92, .96), rgba(34, 48, 70, .95)); --ib-closet: linear-gradient(180deg, rgba(58, 68, 88, .96), rgba(40, 50, 68, .95)); --ib-mail: linear-gradient(180deg, rgba(46, 60, 84, .96), rgba(34, 46, 66, .95)); --ib-board: linear-gradient(180deg, rgba(52, 62, 82, .96), rgba(38, 48, 68, .95)); --ib-door: rgba(70, 92, 124, .95); --ib-line: rgba(255, 255, 255, .34); --ib-edge: rgba(255, 255, 255, .22); --ib-ink: #E8EEF6; --ib-ink2: #A9B6C9; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .oh-root { --ib-fridge: linear-gradient(180deg, rgba(48, 66, 92, .96), rgba(34, 48, 70, .95)); --ib-closet: linear-gradient(180deg, rgba(58, 68, 88, .96), rgba(40, 50, 68, .95)); --ib-mail: linear-gradient(180deg, rgba(46, 60, 84, .96), rgba(34, 46, 66, .95)); --ib-board: linear-gradient(180deg, rgba(52, 62, 82, .96), rgba(38, 48, 68, .95)); --ib-door: rgba(70, 92, 124, .95); --ib-line: rgba(255, 255, 255, .34); --ib-edge: rgba(255, 255, 255, .22); --ib-ink: #E8EEF6; --ib-ink2: #A9B6C9; } }
/* the dialog is the thing: no frame of its own around it (the door sticks out on the right) */
#companion-body .oh-root .oh-sheet:has(.oh-ibox, .oh-board) { background: transparent; border-color: transparent; box-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none; overflow: visible; padding: 8px 12px 8px 8px; max-width: 320px; max-height: none; }
#companion-body .oh-root .oh-sheet:has(.oh-ibox, .oh-board) .oh-close { top: -10px; right: -2px; z-index: 6; width: 32px; height: 32px; min-width: 32px; min-height: 32px; border-radius: 50%; background: var(--gl2); color: var(--gi); font-size: 18px; box-shadow: 0 2px 8px rgba(40, 60, 90, .16); }
.oh-ibox, .oh-board { -webkit-backdrop-filter: blur(14px) saturate(1.2); backdrop-filter: blur(14px) saturate(1.2); }
.oh-ibox { position: relative; border-radius: 30px 30px 22px 22px; padding: 22px 18px 18px; border: 1px solid var(--ib-edge); box-shadow: 0 20px 44px rgba(40, 60, 90, .28), inset 0 0 0 8px rgba(255, 255, 255, .24); color: var(--ib-ink); }
.oh-ibox .oh-ilight { position: absolute; left: 50%; top: 9px; width: 84px; height: 6px; margin-left: -42px; border-radius: 3px; background: rgba(255, 248, 215, .95); box-shadow: 0 0 20px 7px rgba(255, 240, 190, .7); }
.oh-ibox .oh-idoor { position: absolute; right: -24px; top: 18px; bottom: 18px; width: 28px; border-radius: 0 24px 18px 0; border: 1px solid var(--ib-edge); background: var(--ib-door); }
.oh-ibox .oh-it, .oh-board .oh-it { text-align: center; font-size: 18px; font-weight: 600; color: var(--ib-ink); margin-top: 6px; }
.oh-ibox .oh-is, .oh-board .oh-is { text-align: center; font-size: 12px; color: var(--ib-ink2); margin-top: 2px; }
.oh-ibox.fridge { background: var(--ib-fridge); } .oh-ibox.closet { background: var(--ib-closet); } .oh-ibox.mail { background: var(--ib-mail); }
.oh-ishelf { position: relative; margin: 14px 4px 0; min-height: 76px; border-bottom: 3px solid var(--ib-line); display: flex; align-items: flex-end; justify-content: space-around; gap: 4px; padding-bottom: 4px; }
#companion-body .oh-ishelf button, .oh-ishelf .oh-keep { background: none; border: 0; padding: 4px 2px; font: inherit; font-size: 11px; color: var(--ib-ink); cursor: pointer; display: flex; flex-direction: column; align-items: center; gap: 2px; border-radius: 12px; min-width: 44px; min-height: 44px; transition: transform .15s; animation: oh-dropin .5s cubic-bezier(.34, 1.6, .64, 1) both; animation-delay: var(--d, 0s); }
.oh-ishelf .oh-keep { cursor: default; }
#companion-body .oh-ishelf button:active { transform: scale(.92); } #companion-body .oh-ishelf button:hover { background: rgba(255, 255, 255, .28); }
.oh-ishelf img { width: 44px; height: 44px; image-rendering: pixelated; object-fit: contain; }
.oh-ishelf i { font-style: normal; font-size: 10px; color: var(--ib-ink2); }
.oh-ishelf .none { align-self: center; font-size: 12px; color: var(--ib-ink2); text-align: center; }
@keyframes oh-dropin { 0% { opacity: 0; transform: translateY(-16px) scale(.5); } 100% { opacity: 1; transform: none; } }
.oh-irod { position: relative; height: 150px; margin: 18px 6px 0; display: flex; justify-content: space-around; align-items: flex-start; }
.oh-irod::before { content: ''; position: absolute; left: -6px; right: -6px; top: 10px; height: 4px; border-radius: 2px; background: linear-gradient(90deg, #C9A060, #E8C98E, #C9A060); }
#companion-body .oh-irod button { position: relative; margin-top: 6px; background: none; border: 0; padding: 16px 6px 6px; border-radius: 16px; font: inherit; font-size: 12px; color: var(--ib-ink); cursor: pointer; display: flex; flex-direction: column; align-items: center; gap: 4px; min-width: 44px; transition: transform .2s cubic-bezier(.34, 1.5, .64, 1); animation: oh-swingin 1s ease-out both; transform-origin: 50% 0; animation-delay: var(--d, 0s); }
#companion-body .oh-irod button::before { content: ''; position: absolute; top: 0; left: 50%; width: 14px; height: 14px; margin-left: -7px; border: 2px solid #9AA6B6; border-bottom: 0; border-radius: 8px 8px 0 0; }
#companion-body .oh-irod button.on { background: rgba(255, 255, 255, .45); box-shadow: 0 6px 16px rgba(40, 60, 90, .14); }
#companion-body .oh-irod button:hover { transform: translateY(-3px); }
.oh-irod canvas { width: 72px; height: 84px; image-rendering: pixelated; }
@keyframes oh-swingin { 0% { opacity: 0; transform: rotate(-16deg); } 15% { opacity: 1; } 35% { transform: rotate(10deg); } 55% { transform: rotate(-5deg); } 78% { transform: rotate(2deg); } 100% { transform: rotate(0); } }
#companion-body .oh-ilink { display: block; margin: 8px auto 0; min-height: 44px; padding: 0 12px; background: none; border: 0; font: inherit; font-size: 11px; color: var(--ib-ink2); text-decoration: underline; cursor: pointer; }
.oh-board { position: relative; border-radius: 22px; padding: 20px 16px 18px; background: var(--ib-board); border: 1px solid var(--ib-edge); box-shadow: 0 20px 44px rgba(40, 60, 90, .26), inset 0 0 0 6px rgba(201, 160, 96, .35); color: var(--ib-ink); }
.oh-board .oh-it { font-size: 17px; margin-top: 0; } .oh-board .oh-is { margin: 2px 0 6px; }
.oh-board .oh-none { margin: 18px 0 8px; text-align: center; font-size: 13px; color: var(--ib-ink2); }
.oh-note { position: relative; margin: 14px 6px 0; padding: 14px 14px 10px; background: #FFFFFF linear-gradient(transparent 21px, #E3ECF6 22px) 0 8px / 100% 22px; color: #2E3A4F; font-size: 14px; line-height: 22px; border-radius: 4px; box-shadow: 0 6px 14px rgba(40, 60, 90, .14); transform: rotate(var(--r, -1.5deg)); animation: oh-notein .55s cubic-bezier(.34, 1.5, .64, 1) both; animation-delay: var(--d, 0s); overflow-wrap: anywhere; }
.oh-note small { display: block; text-align: right; color: #6B7A90; }
.oh-note::before { content: ''; position: absolute; left: 50%; top: -6px; width: 12px; height: 12px; margin-left: -6px; border-radius: 50%; background: var(--pin, #E8879C); box-shadow: inset -2px -2px 0 rgba(0, 0, 0, .15), 0 2px 3px rgba(0, 0, 0, .2); }
@keyframes oh-notein { 0% { opacity: 0; transform: translateY(-26px) rotate(-14deg); } 100% { opacity: 1; transform: rotate(var(--r, -1.5deg)); } }
.oh-env { position: relative; width: 200px; max-width: 100%; height: 110px; margin: 16px auto 0; border-radius: 10px; background: #FFFFFF; box-shadow: 0 8px 18px rgba(40, 60, 90, .16); cursor: pointer; transform: rotate(var(--r, 0deg)); transition: transform .2s cubic-bezier(.34, 1.5, .64, 1); animation: oh-envup .55s cubic-bezier(.34, 1.4, .64, 1) both; animation-delay: var(--d, 0s); }
.oh-env + .oh-env { margin-top: -70px; }
.oh-env:hover, .oh-env:focus-visible { transform: rotate(var(--r, 0deg)) translateY(-4px); }
.oh-env::before { content: ''; position: absolute; left: 0; right: 0; top: 0; height: 58px; background: linear-gradient(to bottom right, transparent 49.5%, #E3ECF6 50%) left / 50% 100% no-repeat, linear-gradient(to bottom left, transparent 49.5%, #E3ECF6 50%) right / 50% 100% no-repeat; border-radius: 10px 10px 0 0; }
.oh-env b { position: absolute; left: 14px; bottom: 12px; max-width: 110px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; color: #2E3A4F; } .oh-env i { position: absolute; right: 14px; bottom: 12px; font-style: normal; font-size: 11px; color: #6B7A90; }
.oh-env .seal { position: absolute; left: 50%; top: 44px; width: 18px; height: 18px; margin-left: -9px; border-radius: 50%; background: #E8879C; box-shadow: inset -2px -2px 0 rgba(0, 0, 0, .12); }
@keyframes oh-envup { 0% { opacity: 0; transform: translateY(40px) rotate(var(--r, 0deg)) scale(.8); } 100% { opacity: 1; transform: rotate(var(--r, 0deg)); } }
.oh-flyit { position: absolute; z-index: 60; pointer-events: none; image-rendering: pixelated; transition: transform .6s cubic-bezier(.45, -.35, .6, 1), opacity .6s ease-in; }
/* a dialog grows out of the thing that was tapped and shrinks back into it (--dx / --dy = from the middle of the box to that thing) */
.oh-sheet.show.from { animation: oh-popfrom .46s cubic-bezier(.34, 1.25, .64, 1) both; }
.oh-sheet.show.from.stay { animation: none; }
@keyframes oh-popfrom { 0% { opacity: .15; transform: translate(calc(-50% + var(--dx, 0px)), calc(-50% + var(--dy, 0px))) scale(.1); } 100% { opacity: 1; transform: translate(-50%, -50%) scale(1); } }
.oh-sheet.show.shrink { animation: oh-shrinkto .26s cubic-bezier(.55, 0, .75, .2) both !important; }
@keyframes oh-shrinkto { from { opacity: 1; transform: translate(-50%, -50%) scale(1); } to { opacity: 0; transform: translate(calc(-50% + var(--dx, 0px)), calc(-50% + var(--dy, 0px))) scale(.1); } }
/* the weather in the status bar: a little pixel picture; the word is for screen readers */
#companion-body .oh-root .oh-status .wx { width: 14px; height: 14px; image-rendering: pixelated; flex: none; }
#companion-body .oh-root .oh-status .wxt { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
@keyframes oh-fadein { from { opacity: 0; } to { opacity: 1; } }
@keyframes oh-fadeout { from { opacity: 1; } to { opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  .oh-sheet.show.from { animation: oh-fadein .15s both; } .oh-sheet.show.from.stay { animation: none; }
  .oh-sheet.show.shrink { animation: oh-fadeout .12s both !important; }
  #companion-body .oh-ishelf button, #companion-body .oh-irod button, .oh-note, .oh-env { animation: none; }
  .oh-flyit { display: none; }
}
.oh-sheet:not(.show), .oh-sheet.shrink { pointer-events: none; }   /* a dialog that is going away (fading out, shrinking back) never catches a tap meant for the room */

/* ── 摇杆 (js/apps/offline-joystick.js): bottom left of the whole 线下 App, fixed on the screen; hidden while a dialog, 装修 or a face-to-face chat is on ── */
.oh-joy { position: absolute; left: 0; right: 0; bottom: calc(92px + env(safe-area-inset-bottom, 0px)); height: 0; z-index: 30; pointer-events: none; transition: opacity .2s; }
.oh-joy.hide { opacity: 0; }
.oh-joy.hide * { pointer-events: none !important; }
.oh-joy-pad { position: absolute; left: 22px; bottom: 0; width: 104px; height: 104px; border-radius: 50%; background: rgba(255, 255, 255, .28); border: 1px solid rgba(255, 255, 255, .6); box-shadow: inset 0 2px 10px rgba(40, 60, 90, .12); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); pointer-events: auto; touch-action: none; }
.oh-joy-knob { position: absolute; left: 50%; top: 50%; width: 46px; height: 46px; margin: -23px 0 0 -23px; border-radius: 50%; background: rgba(255, 255, 255, .85); box-shadow: 0 4px 12px rgba(40, 60, 90, .25); transition: transform .12s ease-out; }
.oh-joy-pad.on .oh-joy-knob { transition: none; }

/* 家具栏的名称: the icon keeps its place, the name is two lines high (up to 5 characters on one line, a longer one in two lines of about the same length) */
#companion-body .oh-dock-row button { justify-content: flex-start; padding-top: 6px; }
.oh-dock-row button img { flex: 1; min-height: 0; object-fit: contain; }
.oh-dock-row .dn { display: flex; align-items: center; justify-content: center; width: 100%; height: 2.5em; line-height: 1.25; font-size: 11px; text-align: center; word-break: keep-all; overflow-wrap: anywhere; overflow: hidden; flex: none; }
.oh-dock-row .dn em { display: block; font-style: normal; max-width: 100%; }

/* ── 冰箱和灶台 (js/apps/offline-home-kitchen.js; design: _handoff/home-interactions fridge.css / stove.css) ── */

/* ===== 冰箱 v2（2026-10-29 预览）：能开门的冰箱、便签、来源 ===== */
.oh-sheet.glass.ohf-sheet{padding:0;background:transparent;border:0;box-shadow:none;backdrop-filter:none;-webkit-backdrop-filter:none;max-width:318px;width:calc(100% - 28px);overflow:visible;max-height:none}
#companion-body .oh-sheet.glass.ohf-sheet .oh-close{right:-4px;top:-12px;z-index:9;background:var(--gl);border:1px solid var(--gle);border-radius:50%;min-width:38px;min-height:38px;font-size:18px;color:var(--gi);backdrop-filter:blur(14px)}
.ohf{--fb1:#EEF3F8;--fb2:#D5DFEA;--fe:#B9C7D6;--fin:#F6F9FC;--fin2:#E3EBF3;--shelf:rgba(255,255,255,.95);--fink:#2E3A4F;--fink2:#6B7A90;--fh:#C3CEDB;--fhot:#E58FA0;
  position:relative;border-radius:34px 34px 26px 26px;padding:12px 12px 14px;background:linear-gradient(180deg,var(--fb1),var(--fb2));
  box-shadow:0 22px 46px rgba(40,60,90,.3),inset 0 2px 0 rgba(255,255,255,.9),inset 0 -3px 0 rgba(120,140,165,.25);border:1px solid rgba(255,255,255,.9);color:var(--fink);font-size:12px;user-select:none;-webkit-user-select:none}
.ohf.his{--fb1:#E4E8EE;--fb2:#C7CED8;--fe:#A9B3C1;--fin:#F2F4F7;--fin2:#DDE2E9;--fh:#B3BCC8}
.ohf-top{display:flex;align-items:center;justify-content:space-between;margin:0 6px 9px;padding:6px 12px;border-radius:14px;background:rgba(255,255,255,.55);box-shadow:inset 0 1px 2px rgba(80,100,130,.15)}
.ohf-top b{font:600 12px/1 'Noto Serif SC',serif;letter-spacing:.18em}
.ohf-top span{font-size:10px;color:var(--fink2);letter-spacing:.06em}
.ohf-sec{position:relative;border-radius:22px;perspective:900px;background:var(--fe);box-shadow:inset 0 2px 6px rgba(60,80,110,.25)}
.ohf-up{height:292px}.ohf-lo{height:132px;margin-top:10px}
.ohf-gap{height:0}
/* inside */
.ohf-in{position:absolute;inset:5px;border-radius:18px;background:linear-gradient(180deg,var(--fin),var(--fin2));overflow:hidden;opacity:.0;transition:opacity .25s .1s}
.ohf-sec.open .ohf-in{opacity:1}
.ohf-light{position:absolute;left:50%;top:6px;width:80px;height:5px;margin-left:-40px;border-radius:3px;background:#FFF8DC;box-shadow:0 0 18px 8px rgba(255,244,200,.0);opacity:0;transition:opacity .3s .3s,box-shadow .5s .3s}
.ohf-sec.open .ohf-light{opacity:1;box-shadow:0 0 22px 10px rgba(255,244,200,.75)}
.ohf-mist{position:absolute;left:0;right:0;top:0;height:60%;background:radial-gradient(ellipse at 50% 0,rgba(255,255,255,.9),rgba(255,255,255,0) 70%);opacity:0;pointer-events:none}
.ohf-sec.open .ohf-mist{animation:ohfFrMist 1.4s ease-out .25s}
@keyframes ohfFrMist{0%{opacity:0;transform:translateY(-8px)}30%{opacity:.9}100%{opacity:0;transform:translateY(26px)}}
.ohf-cols{position:absolute;left:8px;right:8px;top:18px;bottom:8px;display:flex;gap:6px}
.ohf-main{flex:1;display:flex;flex-direction:column;min-width:0}
.ohf-rack{width:46px;border-radius:12px;background:rgba(255,255,255,.55);box-shadow:inset 0 0 0 1px rgba(255,255,255,.9);display:flex;flex-direction:column;justify-content:space-around;padding:4px 0}
.ohf-rack .rk{border-bottom:3px solid var(--shelf);display:flex;justify-content:center;align-items:flex-end;min-height:56px;gap:0}
.ohf-rack .rk:last-child{border-bottom:0}
.ohf-shelf{position:relative;flex:1;display:flex;align-items:flex-end;justify-content:space-around;border-bottom:3px solid var(--shelf);box-shadow:0 3px 0 rgba(150,170,195,.25);padding:0 2px 1px;min-height:0}
.ohf-shelf .none,.ohf-dr .none{align-self:center;font-size:11px;color:var(--fink2);opacity:.7}
.ohf-it{position:relative;background:none;border:0;padding:2px 2px 0;cursor:pointer;display:flex;flex-direction:column;align-items:center;border-radius:10px;opacity:0;transform:translateY(6px)}
.ohf-sec.open .ohf-it,.ohf-dr.out .ohf-it{animation:ohfFitIn .34s cubic-bezier(.34,1.4,.64,1) forwards;animation-delay:var(--d,0ms)}
@keyframes ohfFitIn{to{opacity:1;transform:none}}
.ohf-it:active{transform:scale(.9)!important}
.ohf-it.sel{background:rgba(91,143,214,.16)}
.ohf-it img{image-rendering:pixelated;display:block}
.ohf-it .n{position:absolute;right:-2px;bottom:-1px;font:600 9px/1 -apple-system,sans-serif;color:#fff;background:rgba(46,58,79,.72);border-radius:7px;padding:2px 4px}
.ohf-it .tag{position:absolute;left:0;top:0;width:7px;height:7px;border-radius:50%;background:var(--fhot);box-shadow:0 0 0 2px #fff}
.ohf-it .tag.out{background:#E7B65C}
.ohf-it .tag.we{background:#7FB38E}
/* crisper drawer */
.ohf-crisp{position:relative;height:56px;margin-top:6px;border-radius:12px;background:rgba(255,255,255,.4);box-shadow:inset 0 0 0 1.5px rgba(255,255,255,.95);overflow:hidden;cursor:pointer}
.ohf-crisp .ohf-row{position:absolute;inset:4px 6px 14px;display:flex;align-items:flex-end;justify-content:space-around;filter:blur(1.6px);opacity:.75;transition:filter .3s,opacity .3s}
.ohf-crisp:after{content:"";position:absolute;inset:0;background:repeating-linear-gradient(90deg,rgba(255,255,255,.35) 0 2px,rgba(255,255,255,0) 2px 5px);pointer-events:none;transition:opacity .3s}
.ohf-crisp b{position:absolute;left:8px;bottom:3px;font-size:9px;font-weight:500;color:var(--fink2);letter-spacing:.06em}
.ohf-crisp i{position:absolute;left:50%;top:3px;width:38px;height:4px;margin-left:-19px;border-radius:2px;background:rgba(46,58,79,.35)}
.ohf-crisp.out{background:rgba(255,255,255,.75);transform:translateY(-2px)}
.ohf-crisp.out .ohf-row{filter:none;opacity:1}.ohf-crisp.out:after{opacity:0}
.ohf-crisp.out .ohf-it{opacity:1;transform:none}
/* doors */
.ohf-door{position:absolute;inset:0;border-radius:22px;background:linear-gradient(170deg,#FBFCFE,var(--fb1) 40%,var(--fb2));box-shadow:inset 0 2px 0 #fff,inset 0 -2px 0 rgba(120,140,165,.3),0 2px 6px rgba(60,80,110,.18);transform-origin:100% 50%;transition:transform .62s cubic-bezier(.5,.05,.25,1.15);z-index:3;backface-visibility:hidden;-webkit-backface-visibility:hidden}
.ohf-sec.open .ohf-door{transform:rotateY(100deg);pointer-events:none}
.ohf-sec.open .ohf-door *{pointer-events:none}
.ohf-handle{position:absolute;left:12px;top:50%;width:22px;height:110px;margin-top:-55px;border-radius:11px;background:linear-gradient(90deg,#fff,#E3E9F0 55%,#C9D3DE);box-shadow:0 3px 8px rgba(60,80,110,.28),inset 0 1px 0 #fff;border:0;cursor:pointer;display:flex;align-items:center;justify-content:center;writing-mode:vertical-rl;font-size:10px;color:var(--fink2);letter-spacing:.3em;padding:0}
.ohf-lo .ohf-handle{height:70px;margin-top:-35px}
.ohf-handle:active{transform:translateX(2px)}
.ohf-handle.frhint{animation:ohfHHint 2.4s ease-in-out infinite}
@keyframes ohfHHint{0%,70%,100%{box-shadow:0 3px 8px rgba(60,80,110,.28)}82%{box-shadow:0 0 0 5px rgba(91,143,214,.25),0 3px 8px rgba(60,80,110,.28)}}
.ohf-plate{position:absolute;left:46px;right:14px;top:50%;transform:translateY(-50%);border-radius:12px;padding:9px 12px;background:rgba(46,58,79,.06);box-shadow:inset 0 1px 2px rgba(60,80,110,.18);font-size:10px;color:var(--fink2);line-height:1.7;letter-spacing:.04em}
.ohf-plate b{display:block;font:600 11px/1.5 'Noto Serif SC',serif;color:var(--fink);letter-spacing:.12em}
/* notes on the door */
.ohf-note{position:absolute;width:118px;min-height:56px;padding:13px 10px 8px;background:#FFFDF7;border-radius:4px;box-shadow:0 4px 10px rgba(60,80,110,.2);transform:rotate(var(--r,0deg));font:13px/1.5 'Noto Serif SC',serif;color:#3B4659;cursor:pointer;text-align:left;border:0;animation:ohfNoteIn .4s cubic-bezier(.34,1.4,.64,1) both;animation-delay:var(--d,0ms)}
.ohf-note:before{content:"";position:absolute;left:50%;top:-6px;width:14px;height:14px;margin-left:-7px;border-radius:50%;background:radial-gradient(circle at 35% 35%,#fff,var(--mg,#9DB7D9) 55%,#6F8DB5);box-shadow:0 2px 3px rgba(40,60,90,.3)}
.ohf-note small{display:block;margin-top:5px;font:10px/1.3 -apple-system,sans-serif;color:#8A96A8}
.ohf-note.me{background:#EAF2FB;--mg:#F2B7C2}
.ohf-note.me:before{background:radial-gradient(circle at 35% 35%,#fff,#F2B7C2 55%,#D88D9C)}
.ohf-note.dash{background:transparent;box-shadow:none;border:1.5px dashed rgba(107,122,144,.55);color:var(--fink2);font:12px/1.4 -apple-system,sans-serif;min-height:40px;width:86px;display:flex;align-items:center;justify-content:center;padding:6px}
.ohf-note.dash:before{display:none}
@keyframes ohfNoteIn{0%{opacity:0;transform:rotate(var(--r,0deg)) translateY(-10px) scale(.9)}100%{opacity:1;transform:rotate(var(--r,0deg))}}
.ohf-note.flash{animation:ohfNoteFlash .9s ease}
@keyframes ohfNoteFlash{30%{transform:rotate(var(--r,0deg)) scale(1.08)}}
/* freezer drawers */
.ohf-fz{position:absolute;left:8px;right:8px;top:8px;bottom:8px;display:flex;flex-direction:column;gap:6px}
.ohf-dr{position:relative;flex:1;border-radius:12px;background:rgba(255,255,255,.45);box-shadow:inset 0 0 0 1.5px rgba(255,255,255,.95);cursor:pointer;display:flex;align-items:flex-end;justify-content:space-around;padding:0 8px 12px;overflow:hidden;transition:background .25s}
.ohf-dr:after{content:"";position:absolute;left:50%;bottom:4px;width:44px;height:4px;margin-left:-22px;border-radius:2px;background:rgba(46,58,79,.35)}
.ohf-dr .ohf-it{opacity:0}
.ohf-dr:not(.out) .ohf-row{filter:blur(1.4px);opacity:.6}
.ohf-dr .ohf-row{display:flex;align-items:flex-end;justify-content:space-around;width:100%;transition:filter .3s,opacity .3s}
.ohf-dr:not(.out) .ohf-it{opacity:1;transform:none;animation:none}
.ohf-dr.out{background:rgba(255,255,255,.8)}
.ohf-dr b{position:absolute;left:10px;top:6px;font-size:9px;font-weight:500;color:var(--fink2);letter-spacing:.06em}
.ohf-legend{display:flex;gap:10px;justify-content:center;margin:9px 0 0;font-size:10px;color:var(--fink2)}
.ohf-legend i{display:inline-block;width:7px;height:7px;border-radius:50%;margin-right:4px;vertical-align:0;background:var(--fhot)}
.ohf-legend i.out{background:#E7B65C}.ohf-legend i.we{background:#7FB38E}
/* detail card */
.oh-pop{position:absolute;left:10px;right:10px;bottom:12px;z-index:8;border-radius:20px;background:rgba(255,255,255,.86);backdrop-filter:blur(18px) saturate(1.4);-webkit-backdrop-filter:blur(18px) saturate(1.4);box-shadow:0 14px 34px rgba(40,60,90,.28);border:1px solid #fff;padding:14px 14px 12px;transform:translateY(14px) scale(.96);opacity:0;visibility:hidden;transition:transform .28s cubic-bezier(.34,1.3,.64,1),opacity .2s,visibility 0s .28s}
.oh-pop.show{transform:none;opacity:1;visibility:visible;transition:transform .28s cubic-bezier(.34,1.3,.64,1),opacity .2s}
.oh-pop .ch{display:flex;gap:12px;align-items:center}
.oh-pop h4{margin:0;font:600 15px/1.3 'Noto Serif SC',serif;color:var(--fink)}
.oh-pop .src{margin-top:3px;font-size:11px;color:var(--fink2);line-height:1.45}
.oh-pop .q{margin:10px 0 0;padding:8px 11px;border-radius:12px;background:#FFFDF7;font:13px/1.55 'Noto Serif SC',serif;color:#3B4659;box-shadow:inset 0 0 0 1px rgba(160,170,190,.2)}
.oh-pop .q small{display:block;font:10px/1.3 -apple-system,sans-serif;color:#8A96A8;margin-top:3px}
.oh-pop .ca{display:flex;gap:8px;margin-top:11px}
.oh-pop .ca button{flex:1;min-height:36px;border:0;border-radius:18px;background:rgba(46,58,79,.07);color:var(--fink);font:inherit;font-size:13px;cursor:pointer}
.oh-pop .ca button.p{background:#3F74BF;color:#fff}
.oh-pop textarea{width:100%;box-sizing:border-box;margin-top:10px;min-height:64px;resize:none;border:0;border-radius:12px;padding:9px 11px;background:#FFFDF7;font:14px/1.5 'Noto Serif SC',serif;color:#3B4659;box-shadow:inset 0 0 0 1px rgba(160,170,190,.3);outline:none}
.oh-pop .hint2{font-size:10px;color:#8A96A8;margin-top:6px}
.oh-pop-dim{position:absolute;inset:0;z-index:7;border-radius:34px 34px 26px 26px;background:rgba(40,52,72,.12);opacity:0;visibility:hidden;transition:opacity .2s,visibility 0s .2s}
.oh-pop-dim.show{opacity:1;visibility:visible;transition:opacity .2s}
.ohf-crisp .ohf-it{opacity:1!important;transform:none!important;animation:none!important}
.ohf-sec:after{content:"";position:absolute;right:-8px;top:8px;bottom:8px;width:9px;border-radius:0 8px 8px 0;background:linear-gradient(90deg,#FBFCFE,var(--fb2));box-shadow:2px 0 4px rgba(60,80,110,.2);opacity:0;transform:scaleX(.2);transform-origin:left;transition:opacity .2s .35s,transform .3s .35s;z-index:4}
.ohf-sec.open:after{opacity:1;transform:none}
.ohf-door>*{transition:opacity .2s .25s}
.ohf-sec.open .ohf-door>*{opacity:0!important}
.ohf-sec.open .ohf-door{opacity:0;transition:transform .62s cubic-bezier(.5,.05,.25,1.15),opacity .15s .5s}
.ohf-top span.fr-close{cursor:pointer;color:var(--fink);padding:4px 0 4px 10px}

/* 气泡卡：从点的东西旁边冒出来（2026-10-29 改） */
.oh-pop{left:0;right:auto;bottom:auto;top:0;width:224px;box-sizing:border-box;border-radius:16px;padding:11px 12px 10px;background:rgba(255,255,255,.95);box-shadow:0 10px 26px rgba(40,60,90,.26);transform:scale(.9);transition:transform .22s cubic-bezier(.34,1.4,.64,1),opacity .15s,visibility 0s .22s}
.oh-pop.up{transform-origin:var(--tx) 100%}.oh-pop.down{transform-origin:var(--tx) 0}
.oh-pop.show{transform:none}
.oh-pop:after{content:"";position:absolute;left:var(--tx);width:12px;height:12px;margin-left:-6px;background:inherit;transform:rotate(45deg);border-radius:2px}
.oh-pop.up:after{bottom:-6px;box-shadow:3px 3px 4px rgba(40,60,90,.08)}
.oh-pop.down:after{top:-6px}
.oh-pop h4{font-size:14px}
.oh-pop .src{font-size:10.5px;margin-top:2px}
.oh-pop .q{margin-top:8px;padding:7px 9px;font-size:12.5px;line-height:1.5;border-radius:10px}
.oh-pop .ca{margin-top:9px;gap:6px}
.oh-pop .ca button{min-height:30px;font-size:12px;border-radius:15px}
.oh-pop textarea{min-height:52px;font-size:13px;margin-top:8px}
.oh-pop-dim{background:transparent}


/* ===== 灶台（2026-10-29 预览） ===== */
.oh-sheet.glass.ohs-sheet{max-width:330px;padding:18px 14px 14px}
.ohs-h{display:flex;align-items:baseline;gap:8px;margin:0 36px 10px 4px}
.ohs-h b{font:600 17px/1.2 'Noto Serif SC',serif;color:var(--gi)}
.ohs-h span{font-size:11px;color:var(--gi2)}
.ohs-list{display:flex;flex-direction:column;gap:6px;max-height:46vh;overflow:auto;scrollbar-width:none;padding:2px}
.ohs-list::-webkit-scrollbar{display:none}
.ohs-row{display:flex;align-items:center;gap:10px;width:100%;text-align:left;border:0;border-radius:16px;padding:7px 10px 7px 7px;background:rgba(255,255,255,.5);color:var(--gi);font:inherit;cursor:pointer;box-shadow:inset 0 0 0 1px rgba(255,255,255,.7);transition:background .15s,box-shadow .15s,transform .12s;position:relative;box-sizing:border-box}
.ohs-row:active{transform:scale(.98)}
.ohs-row.on{background:rgba(255,255,255,.92);box-shadow:inset 0 0 0 2px rgba(91,143,214,.75)}
.ohs-row.off{opacity:.55;cursor:default}
.ohs-ico{width:52px;height:52px;flex:none;border-radius:12px;background:linear-gradient(180deg,#F6F9FC,#E3EBF3);display:flex;align-items:center;justify-content:center}
.ohs-ico img{image-rendering:pixelated}
.ohs-pen{font-size:20px;color:var(--gi2)}
.ohs-tt{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px}
.ohs-tt b{font:600 14px/1.25 'Noto Serif SC',serif}
.ohs-tt b em{font:400 10px -apple-system,sans-serif;color:#C9893A;margin-left:6px;font-style:normal}
.ohs-chips{display:flex;flex-wrap:wrap;gap:4px}
.ohs-chip{display:inline-flex;align-items:center;gap:3px;font-size:10px;color:var(--gi2);background:rgba(46,58,79,.06);border-radius:8px;padding:1px 6px 1px 2px}
.ohs-chip img{width:auto!important;height:auto!important;image-rendering:pixelated}
.ohs-chip.no{color:#C0707E;padding-left:6px}
.ohs-buy{flex:none;font-size:11px;color:#5B8FD6;padding:6px 8px;border-radius:12px;background:rgba(91,143,214,.12);opacity:1}
.ohs-row.off .ohs-buy{opacity:1}
.ohs-free input{border:0;outline:none;background:rgba(46,58,79,.06);border-radius:8px;padding:5px 8px;font:13px 'Noto Serif SC',serif;color:var(--gi);width:100%;box-sizing:border-box}
.ohs-seg{display:flex;gap:4px;margin:12px 0 0;padding:3px;border-radius:16px;background:rgba(46,58,79,.07)}
.ohs-seg button{flex:1;min-height:32px;border:0;border-radius:13px;background:none;font:inherit;font-size:12px;color:var(--gi2);cursor:pointer}
.ohs-seg button.on{background:#fff;color:var(--gi);box-shadow:0 1px 4px rgba(40,60,90,.15)}
.ohs-go{width:100%;min-height:42px;margin-top:10px;border:0;border-radius:21px;background:#3F74BF;color:#fff;font:600 15px 'Noto Serif SC',serif;letter-spacing:.3em;cursor:pointer}
.ohs-go:disabled{opacity:.4;cursor:default}
.ohf-carry{position:absolute;z-index:30;pointer-events:none;image-rendering:pixelated;animation:carryBob .5s ease-in-out infinite alternate}
@keyframes carryBob{to{transform:translateY(-3px)}}
.ohf-stovefx{position:absolute;left:0;top:0;pointer-events:none}

.ohf-empty{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;font:600 14px 'Noto Serif SC',serif;color:var(--fink2)}
.ohf-empty button{border:0;border-radius:16px;padding:8px 16px;background:rgba(91,143,214,.14);color:#5B8FD6;font:inherit;font-size:12px;cursor:pointer}
.ohf-more{align-self:center;font:600 11px -apple-system,sans-serif;color:var(--fink2);padding:0 6px}
.oh-pop .ch{display:flex;gap:10px;align-items:center}
.oh-pop .ch img{image-rendering:pixelated;width:auto;height:auto;max-width:48px}
.oh-pop .cnt{font:400 12px -apple-system,sans-serif;color:var(--fink2)}
.ohf-who{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}
.ohf-who button{border:0;border-radius:15px;padding:6px 12px;background:rgba(91,143,214,.14);color:var(--fink);font:inherit;font-size:12px;cursor:pointer}
.oh-pop{position:absolute}
.ohs-row.dim{opacity:.6;cursor:default}
.ohs-chip img{width:auto;height:auto;image-rendering:pixelated}
.ohf-carry{position:absolute;pointer-events:none;image-rendering:pixelated;z-index:2}
.ohf-stovefx{position:absolute;left:0;top:0;width:0;height:0;pointer-events:none}
@media (prefers-reduced-motion: reduce) { .ohf-door { transition: none; } .ohf-it, .ohf-note { animation-duration: .01s; } }

.oh-pop { --fink: #2E3A4F; --fink2: #6B7A90; --fin: #F6F9FC; --fin2: #E3EBF3; }   /* the card is used outside the fridge too (the table, later the desk ...) */
.oh-pop textarea { resize: none !important; }

/* ===== 书桌 (js/apps/offline-home-desk.js): drawn in code - the wall with a lamp, the wooden top with the diary / the paper / the 集章册, two drawers (信, 收藏). The bubbles are .oh-pop (offline-home-pop.js). ===== */
.oh-sheet.glass.ohd-sheet{padding:0;background:transparent;border:0;box-shadow:none;backdrop-filter:none;-webkit-backdrop-filter:none;max-width:318px;width:calc(100% - 28px);overflow:visible;max-height:none}
#companion-body .oh-sheet.glass.ohd-sheet .oh-close{right:-4px;top:-12px;z-index:13;background:var(--gl);border:1px solid var(--gle);border-radius:50%;min-width:38px;min-height:38px;font-size:18px;color:var(--gi);backdrop-filter:blur(14px)}
.ohd{--wood1:#D9B48A;--wood2:#C49A6C;--wood3:#A97F55;--wd:#8E6844;--fink:#2E3A4F;--fink2:#6B7A90;--fin:#F6F9FC;--fin2:#E3EBF3;
  position:relative;border-radius:30px;overflow:visible;color:var(--fink);font-size:12px;user-select:none;-webkit-user-select:none;filter:drop-shadow(0 20px 40px rgba(40,60,90,.3))}
.ohd-wall{position:relative;height:150px;border-radius:30px 30px 0 0;background:linear-gradient(180deg,#E9EEF5,#DCE4EE);overflow:hidden;transition:background .4s}
.ohd.lit .ohd-wall{background:linear-gradient(180deg,#EFE8DD,#E6DCCB)}
.ohd-glow{position:absolute;left:8px;top:40px;width:200px;height:200px;border-radius:50%;background:radial-gradient(circle,rgba(255,226,160,.75),rgba(255,226,160,0) 65%);opacity:0;transition:opacity .4s;pointer-events:none}
.ohd.lit .ohd-glow{opacity:1}
.ohd-title{position:absolute;left:20px;top:16px;text-align:left}
.ohd-title b{display:block;font:600 17px/1.2 'Noto Serif SC',serif;letter-spacing:.2em}
.ohd-title span{font-size:10px;color:var(--fink2)}
.ohd-lamp{position:absolute;left:22px;bottom:0;background:none;border:0;padding:0;cursor:pointer;z-index:2}
.ohd-lamp img{image-rendering:pixelated;display:block;transform-origin:bottom center}
.ohd-lamp:active img{transform:scale(.95)}
.ohd-top{position:relative;height:74px;background:linear-gradient(180deg,var(--wood1),var(--wood2));box-shadow:inset 0 3px 0 rgba(255,255,255,.35)}
.ohd-top .ohd-row{position:absolute;left:96px;right:12px;bottom:14px}
.ohd-row{display:flex;align-items:flex-end;justify-content:space-around;gap:6px}
.ohd-edge{height:12px;background:linear-gradient(180deg,var(--wood3),var(--wd));box-shadow:0 3px 6px rgba(60,40,20,.25)}
.ohd-front{position:relative;padding:10px 12px 14px;border-radius:0 0 24px 24px;background:linear-gradient(180deg,var(--wood2),var(--wood3));display:flex;flex-direction:column;gap:8px}
.ohd-dr{position:relative;border-radius:10px}
.ohd-face{position:relative;height:46px;border-radius:10px;background:linear-gradient(180deg,#DDBB93,#CDA477);box-shadow:inset 0 2px 0 rgba(255,255,255,.35),inset 0 -2px 0 rgba(90,60,30,.25),0 2px 4px rgba(60,40,20,.2);cursor:pointer;display:flex;align-items:center;justify-content:center;gap:10px;transition:transform .3s cubic-bezier(.34,1.3,.64,1)}
.ohd-face i{width:34px;height:8px;border-radius:4px;background:linear-gradient(180deg,#F4EDE2,#BFAE96);box-shadow:0 1px 2px rgba(60,40,20,.35)}
.ohd-face span{position:absolute;right:14px;font-size:10px;color:rgba(70,45,20,.55);letter-spacing:.1em}
.ohd-tray{height:0;overflow:hidden;border-radius:10px 10px 0 0;background:linear-gradient(180deg,#F4ECDF,#E8DCC8);box-shadow:inset 0 6px 8px rgba(90,60,30,.18);transition:height .35s cubic-bezier(.34,1.2,.64,1)}
.ohd-dr.out .ohd-tray{height:78px}
.ohd-dr.out .ohd-face{border-radius:0 0 10px 10px}
.ohd-tray .ohd-row{height:100%;padding:0 10px 8px;box-sizing:border-box}
.ohd-tray .none{align-self:center;color:rgba(70,45,20,.5);font-size:11px}
.ohd-obj{position:relative;background:none;border:0;padding:3px;cursor:pointer;border-radius:10px;opacity:0;transform:translateY(5px);animation:ohfFitIn .34s cubic-bezier(.34,1.4,.64,1) forwards;animation-delay:var(--d,0ms)}
.ohd-obj img{image-rendering:pixelated;display:block}
.ohd-obj.sel{background:rgba(255,255,255,.45)}
.ohd-obj:active{transform:scale(.92)!important}
.ohd-obj .n{position:absolute;right:-2px;bottom:-1px;font:600 9px/1 -apple-system,sans-serif;color:#fff;background:rgba(46,58,79,.72);border-radius:7px;padding:2px 4px}
.ohd .oh-pop-dim{border-radius:30px}
.ohd-fly{position:absolute;z-index:20;image-rendering:pixelated;pointer-events:none;transition:transform .8s cubic-bezier(.5,-0.3,.6,1),opacity .8s ease-in}
.ohd-fly.go{transform:translate(120px,-260px) rotate(18deg) scale(.6);opacity:0}
.ohd-top .ohd-row{left:90px}
.ohd-paper{border-radius:12px;background:#FFFDF7;box-shadow:inset 0 0 0 1px rgba(160,170,190,.25);padding:4px 12px 2px;background-image:repeating-linear-gradient(180deg,transparent 0 25px,rgba(160,175,200,.25) 25px 26px);background-position:0 30px}
.ohd-paper input{width:100%;border:0;outline:none;background:transparent;font:600 13px/30px 'Noto Serif SC',serif;color:#3B4659;padding:0;border-bottom:1px solid rgba(160,175,200,.45)}
.oh-pop .ohd-paper textarea{margin:0;min-height:78px;background:transparent;box-shadow:none;border-radius:0;padding:0;font:13px/26px 'Noto Serif SC',serif}
.ohd-paper+.src{margin-top:6px}
.ohd-rows{margin-top:8px;display:flex;flex-direction:column;gap:6px}
.ohd-row2{padding:7px 10px;border-radius:10px;background:#FFFDF7;box-shadow:inset 0 0 0 1px rgba(160,170,190,.2)}
.oh-pop .q.ohd-dq{margin-top:8px}
.ohd-obj.ohd-env em{display:block;font:500 9px/1.2 -apple-system,sans-serif;font-style:normal;color:rgba(70,45,20,.6);margin-top:2px;white-space:nowrap}
.ohd-dr-l.out .ohd-tray{height:86px}
.ohd-letter{border-radius:12px;background:#FFFDF7;box-shadow:inset 0 0 0 1px rgba(160,170,190,.22);padding:11px 13px 10px}
.ohd-l-head{display:flex;gap:10px;align-items:center;padding-bottom:8px;border-bottom:1px dashed rgba(160,175,200,.5)}
.ohd-l-head img{image-rendering:pixelated;flex:none}
.ohd-l-head b{display:block;font:600 14px/1.35 'Noto Serif SC',serif;color:#2E3A4F}
.ohd-l-head span{font-size:10px;color:#8A96A8}
.ohd-l-body{max-height:168px;overflow:auto;scrollbar-width:none;margin-top:8px;font:13px/26px 'Noto Serif SC',serif;color:#3B4659;background-image:repeating-linear-gradient(180deg,transparent 0 25px,rgba(160,175,200,.22) 25px 26px)}
.ohd-l-body::-webkit-scrollbar{display:none}
.ohd-l-sign{text-align:right;font:12px 'Noto Serif SC',serif;color:#6B7A90;margin-top:4px}
.ohd-rows{max-height:210px;overflow:auto;scrollbar-width:none}
.ohd-rows::-webkit-scrollbar{display:none}
button.ohd-l-row{padding:7px 10px;border-radius:10px;background:#FFFDF7;box-shadow:inset 0 0 0 1px rgba(160,170,190,.2);content-visibility:auto;contain-intrinsic-size:auto 52px;display:flex;gap:10px;align-items:center;width:100%;border:0;text-align:left;cursor:pointer;font:inherit}
.ohd-l-row img{image-rendering:pixelated;flex:none}
.ohd-l-row span{display:flex;flex-direction:column}
.ohd-l-row span b{font:600 13px/1.35 'Noto Serif SC',serif;color:#2E3A4F;margin:0}
.ohd-l-row span small{font-size:10px;color:#8A96A8}

.ohd-dr-l .ohd-row{justify-content:center;gap:0;padding-top:10px}
.ohd-dr-l .ohd-obj.ohd-env{margin:0 3px;transform:rotate(var(--rt,0deg))}
.ohd-dr-l .ohd-obj.ohd-env:nth-child(odd){--rt:-4deg}.ohd-dr-l .ohd-obj.ohd-env:nth-child(even){--rt:3deg}
.ohd-dr-l .ohd-obj.ohd-env.sel{background:none;transform:rotate(var(--rt)) translateY(-4px)}
.ohd-obj.ohd-env em{text-align:center}

.ohd-to{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin-bottom:8px}
.ohd-to span{font-size:11px;color:#8A96A8;margin-right:2px}
.ohd-to button{border:0;border-radius:13px;padding:5px 11px;background:rgba(46,58,79,.06);font:12px 'Noto Serif SC',serif;color:#3B4659;cursor:pointer}
.ohd-to button.on{background:#3F74BF;color:#fff}
.oh-pop .ca button:disabled{opacity:.4;cursor:default}

.ohd-dr-l .ohd-obj.ohd-bundle{margin-left:10px}
.ohd-l-chips{display:flex;gap:6px;overflow-x:auto;scrollbar-width:none;margin:8px 0 2px;padding-bottom:2px}
.ohd-l-chips::-webkit-scrollbar{display:none}
.ohd-l-chips button{flex:none;border:0;border-radius:13px;padding:5px 11px;background:rgba(46,58,79,.06);font:12px 'Noto Serif SC',serif;color:#3B4659;cursor:pointer}
.ohd-l-chips button.on{background:#3F74BF;color:#fff}
.ohd-l-list{max-height:260px;margin-top:8px;display:flex;flex-direction:column;gap:6px;overflow:auto;scrollbar-width:none}
.ohd-l-list::-webkit-scrollbar{display:none}
.ohd-l-month{position:sticky;top:0;z-index:1;font-size:10px;letter-spacing:.15em;color:#8A96A8;background:rgba(255,255,255,.95);padding:6px 2px 3px}

.ohd-page{position:absolute;inset:0;z-index:12;border-radius:30px;background:#FCFBF8;padding:14px 16px 16px;display:flex;flex-direction:column;opacity:0;visibility:hidden;transform:translateY(8px);transition:opacity .22s,transform .22s,visibility 0s .22s;box-sizing:border-box}
.ohd-page.show{opacity:1;visibility:visible;transform:none;transition:opacity .22s,transform .22s}
.ohd-back{align-self:flex-start;border:0;background:none;font:13px 'Noto Serif SC',serif;color:#5B8FD6;padding:4px 0;cursor:pointer}
.ohd-ph{display:flex;align-items:baseline;justify-content:space-between;margin:4px 0 4px}
.ohd-ph b{font:600 17px 'Noto Serif SC',serif;color:#2E3A4F;letter-spacing:.1em}
.ohd-ph span{font-size:10.5px;color:#8A96A8}
.ohd-page .ohd-l-list{flex:1;max-height:none;min-height:0}
.ohd-page .ohd-l-month{background:#FCFBF8}
.ohd-page .ohd-letter.full{flex:1;min-height:0;display:flex;flex-direction:column;margin-top:6px}
.ohd-page .ohd-letter.full .ohd-l-body{max-height:none;flex:1}

.ohd-nowrite{margin:0;font-size:12px}
.ohd-none{text-align:center;font-size:11px;color:#8A96A8;padding:18px 0}
.ohd .oh-pop .cnt{margin-left:4px}

/* ===== 墙上三件东西 (js/apps/offline-home-wall.js): 挂历 (.ohc, a paper on the wall), 时钟 (.ohk, in the glass dialog), 软木板 (.ohb, the dialog is the board). The bubbles are .oh-pop. ===== */
#companion-body .oh-root .oh-sheet.glass.ohc-sheet,#companion-body .oh-root .oh-sheet.glass.ohb-sheet{padding:0;background:transparent;border:0;box-shadow:none;backdrop-filter:none;-webkit-backdrop-filter:none;overflow:visible;max-height:none;max-width:330px;width:calc(100% - 28px)}
#companion-body .oh-sheet.glass.ohc-sheet .oh-close,#companion-body .oh-sheet.glass.ohb-sheet .oh-close{right:-4px;top:-12px;z-index:13;background:var(--gl);border:1px solid var(--gle);border-radius:50%;min-width:38px;min-height:38px;font-size:18px;color:var(--gi);backdrop-filter:blur(14px)}
#companion-body .oh-root .oh-sheet.glass.ohk-sheet{max-width:330px}

/* 挂历 */
.ohc{position:relative;padding-top:18px;color:#2E3A4F;user-select:none;-webkit-user-select:none}
.ohc-hang{position:absolute;left:0;right:0;top:0;height:30px;z-index:3;display:flex;justify-content:center;gap:120px;pointer-events:none}
.ohc-hang i{width:12px;height:28px;border-radius:7px;border:3px solid #9AA6B6;border-bottom-color:transparent;box-sizing:border-box;box-shadow:inset 0 1px 0 #fff}
.ohc-page{position:relative;border-radius:10px 10px 18px 18px;background:#FCFBF8;box-shadow:0 18px 40px rgba(40,60,90,.3),0 2px 0 #E9E5DC,0 4px 0 #F4F1EA,0 6px 0 #E6E1D6;overflow:hidden;padding-bottom:12px}
.ohc.flip .ohc-art,.ohc.flip .ohc-grid,.ohc.flip .ohc-memo{animation:ohcIn .24s ease-out}
@keyframes ohcIn{from{opacity:0}to{opacity:1}}
.ohc-art{position:relative;height:112px;background-size:cover;background-position:center;border-bottom:1px solid #EEE9DF}
.ohc-art:before{content:"";position:absolute;inset:0;background:linear-gradient(90deg,rgba(252,251,248,.85),rgba(252,251,248,0) 55%)}
.ohc-mn{position:absolute;left:16px;bottom:12px;display:flex;align-items:flex-end;gap:8px}
.ohc-mn b{font:600 46px/0.9 'Noto Serif SC',serif;color:#3B4659;letter-spacing:-.02em}
.ohc-mn span{display:flex;flex-direction:column;font:600 14px/1.3 'Noto Serif SC',serif;color:#3B4659;padding-bottom:2px}
.ohc-mn em{font:500 9px/1.4 -apple-system,sans-serif;letter-spacing:.22em;color:#5F6E84;font-style:normal}
.ohc-nav{display:flex;align-items:center;justify-content:space-between;padding:8px 10px 2px}
.ohc-nav span{font-size:11px;color:#5F6E84;letter-spacing:.08em}
#companion-body .ohc-nav button{width:44px;height:36px;border:0;border-radius:18px;background:rgba(46,58,79,.05);font-size:18px;line-height:1;color:#55667E;cursor:pointer}
.ohc-wd,.ohc-grid{display:grid;grid-template-columns:repeat(7,1fr);padding:0 10px}
.ohc-wd span{text-align:center;font-size:10px;color:#5F6E84;padding:6px 0 4px}
.ohc-wd span.wk{color:#B0586B}
#companion-body .ohc-cd{position:relative;height:38px;border:0;background:none;font:500 14px/1 'Noto Serif SC',serif;color:#2E3A4F;cursor:pointer;display:flex;flex-direction:column;align-items:center;justify-content:flex-start;padding:7px 0 0;border-radius:10px}
.ohc-cd.e{cursor:default}
.ohc-cd.wk{color:#B0586B}
.ohc-cd.past{color:#66758A}
.ohc-cd.sel{background:rgba(91,143,214,.12)}
.ohc-cd.per:before{content:"";position:absolute;left:0;right:0;top:4px;height:22px;background:rgba(242,183,194,.35);z-index:-1}
.ohc-cd.per.predicted:before{background:none;border-top:1.5px dashed rgba(216,141,156,.6);border-bottom:1.5px dashed rgba(216,141,156,.6);box-sizing:border-box}
.ohc-grid{position:relative;z-index:0}
.ohc-cd.today:after{content:"";position:absolute;left:50%;top:1px;width:30px;height:26px;margin-left:-15px;border:2px solid #E0707F;border-radius:48% 52% 45% 55%/55% 45% 55% 45%;transform:rotate(-8deg);box-sizing:border-box}
.ohc-mks{display:flex;gap:2px;margin-top:3px;height:9px}
.ohc-mk{font-style:normal;font-size:9px;line-height:9px;color:#5F6E84}
.ohc-m-date{color:#C0394F}.ohc-m-anniv{color:#8A5F0A}.ohc-m-bday{color:#9C55B0}.ohc-m-his{color:#3F74BF}.ohc-m-sched{color:#55667E;font-size:7px}.ohc-m-custom{color:#5F6E84}.ohc-m-done{color:#4F7556}
.ohc-memo{margin:6px 14px 0;padding-top:8px;border-top:1px dashed #E3DED3}
.ohc-memo-h{font-size:10px;color:#5F6E84;letter-spacing:.2em;margin-bottom:4px}
.ohc-cm{font:13px/1.8 'Noto Serif SC',serif;color:#3B4659}
.ohc-cm b{display:inline-block;min-width:38px;font-weight:600;color:#3F74BF}
.ohc-cm.none{color:#66758A;font-size:12px}
.ohc-legend{display:flex;flex-wrap:wrap;gap:4px 12px;justify-content:center;margin:10px 10px 0;font-size:10px;color:#5F6E84}
.ohc-legend .ohc-mk{margin-right:3px}
.ohc-lg-per{display:inline-block;width:12px;height:7px;background:rgba(242,183,194,.6);margin-right:4px}
.ohc-ev{display:flex;gap:8px;align-items:flex-start;margin-top:8px}
.ohc-ev .ohc-mk{font-size:13px;line-height:18px;width:12px;text-align:center}
.ohc-ev b{display:block;font:600 13px/1.4 'Noto Serif SC',serif;color:#2E3A4F}
.ohc-ev small{display:block;font-size:10px;color:#5F6E84}
.ohc .oh-pop-dim{border-radius:18px}
.ohc-add{display:flex;align-items:center;gap:8px;margin-top:10px;padding-top:9px;border-top:1px dashed #E3DED3}
.ohc-add input{flex:1;min-width:0;border:0;outline:none;background:transparent;font:13px/1.6 'Noto Serif SC',serif;color:#2E3A4F;padding:2px 0;border-bottom:1px solid transparent;transition:border-color .2s}
.ohc-add input:focus{border-bottom-color:rgba(63,116,191,.5)}
.ohc-add input::placeholder{color:#5F6E84;opacity:1}
.ohb .oh-pop textarea::placeholder{color:#5F6E84;opacity:1}
.ohc-add .pen{color:#66758A;font-size:13px}
#companion-body .ohc-add button{flex:none;width:30px;height:30px;border:0;border-radius:50%;background:#3F74BF;color:#fff;font-size:14px;line-height:30px;cursor:pointer;opacity:.35;transition:opacity .2s}
#companion-body .ohc-add.on button{opacity:1}
.ohc-none{font-size:12px;color:#5F6E84;margin-top:6px}
.ohc-opt{display:none;align-items:center;gap:5px;flex-wrap:wrap;margin-top:8px}
.ohc-opt.open{display:flex}
.ohc-opt span{font-size:10px;color:#5F6E84;width:24px;flex:none}
#companion-body .ohc-opt button{border:0;border-radius:12px;padding:5px 10px;background:rgba(46,58,79,.06);font:11.5px 'Noto Serif SC',serif;color:#3B4659;cursor:pointer}
#companion-body .ohc-opt button.on{background:#3F74BF;color:#fff}
@media (max-height:720px){.ohc-art{height:86px}.ohc-mn b{font-size:38px}.ohc-cd{height:31px;padding-top:5px}.ohc-cm{line-height:1.6}.ohc-legend{margin-top:6px}}

/* 时钟 */
.ohk-hd{display:flex;align-items:baseline;gap:8px;margin:0 36px 8px 2px}
.ohk-hd b{font:600 17px 'Noto Serif SC',serif;color:var(--gi)}
.ohk-hd span{font-size:11px;color:var(--gi2)}
.ohk-top{display:flex;align-items:center;gap:16px;padding:4px 4px 12px}
.ohk-face{width:112px;height:112px;flex:none;filter:drop-shadow(0 6px 12px rgba(60,40,20,.2))}
.ohk-rim{fill:#C9A37A}.ohk-dial{fill:#FBF7EF}
.ohk-tick{stroke:#6B5A48;stroke-width:1.2;stroke-linecap:round}.ohk-tick.big{stroke-width:2.2}
.ohk-h{stroke:#3B4659;stroke-width:3.4;stroke-linecap:round}.ohk-m{stroke:#3B4659;stroke-width:2.2;stroke-linecap:round}.ohk-s{stroke:#E0707F;stroke-width:.9;stroke-linecap:round}
.ohk-pin{fill:#3B4659}.ohk-pin2{fill:#E0707F}
.ohk-now b{display:block;font:600 36px/1 'Noto Serif SC',serif;color:var(--gi);letter-spacing:.02em}
.ohk-now span{display:block;margin-top:6px;font-size:12px;color:var(--gi2)}
.ohk-sec{margin-top:6px;padding:10px 12px;border-radius:16px;background:rgba(255,255,255,.85);box-shadow:inset 0 0 0 1px rgba(255,255,255,.7);color:#2E3A4F}
.ohk-st{font-size:10px;letter-spacing:.2em;color:#5F6E84;margin-bottom:4px}
.ohk-line{display:flex;align-items:center;justify-content:space-between;min-height:38px;font-size:13px;color:#2E3A4F}
.ohk-line span{white-space:nowrap}
.ohk-line input[type=time]{flex:none;width:100px;min-width:0;box-sizing:border-box;border:0;background:rgba(46,58,79,.06);border-radius:10px;padding:6px 8px;min-height:32px;font:600 14px 'Noto Serif SC',serif;color:#2E3A4F}
.ohk-row{display:flex;align-items:center;gap:10px;padding:8px 0}
.ohk-row+.ohk-row{border-top:1px solid rgba(46,58,79,.06)}
.ohk-av{width:32px;height:32px;border-radius:50%;flex:none;color:#fff;font:600 13px/32px 'Noto Serif SC',serif;text-align:center;overflow:hidden}
.ohk-av .oh-faceimg{width:100%;height:100%;object-fit:cover;display:block}
.ohk-who{flex:1;min-width:0}
.ohk-who b{display:flex;align-items:center;gap:5px;font:600 13px 'Noto Serif SC',serif;color:#2E3A4F}
.ohk-who span{display:block;font-size:11px;color:#5F6E84;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ohk-dot{width:6px;height:6px;border-radius:50%;background:#7FB38E}
.ohk-dot.busy{background:#E7B65C}.ohk-dot.sleep{background:#9AA6B6}
.ohk-t{text-align:right;flex:none}
.ohk-t b{display:block;font:600 18px/1.1 'Noto Serif SC',serif;color:#2E3A4F}
.ohk-t span{font-size:10px;color:#5F6E84}

/* 软木板 */
.ohb{position:relative;filter:drop-shadow(0 20px 40px rgba(40,60,90,.3))}
.ohb-frame{border-radius:18px;padding:10px;background:linear-gradient(160deg,#C9A37A,#A97F55);box-shadow:inset 0 2px 0 rgba(255,255,255,.35),inset 0 -2px 0 rgba(70,45,20,.3)}
.ohb-cork{border-radius:10px;padding:14px 12px 16px;background-color:#8E6844;background-image:radial-gradient(rgba(120,80,40,.22) 1px,transparent 1.4px),radial-gradient(rgba(255,240,215,.25) 1px,transparent 1.4px);background-size:7px 7px,11px 11px;background-position:0 0,3px 4px;box-shadow:inset 0 2px 8px rgba(70,45,20,.35)}
.ohb-h b{display:inline-block;font:600 15px 'Noto Serif SC',serif;color:#FFFBF2;letter-spacing:.2em;text-shadow:0 1px 2px rgba(70,45,20,.55)}
.ohb-notes{display:grid;grid-template-columns:1fr 1fr;gap:12px 10px;margin-top:10px;max-height:44vh;overflow:auto;scrollbar-width:none;padding:6px 2px}
.ohb-notes::-webkit-scrollbar{display:none}
.ohb-note{position:relative;min-height:92px;padding:16px 10px 8px;background:#E6F0FB;box-shadow:0 4px 8px rgba(70,45,20,.3);transform:rotate(var(--r));animation:ohbIn .4s cubic-bezier(.34,1.4,.64,1) both;animation-delay:var(--d);display:flex;flex-direction:column}
.ohb-note.me{background:#FBE6EA}
@keyframes ohbIn{from{opacity:0;transform:rotate(var(--r)) translateY(-10px) scale(.9)}to{opacity:1;transform:rotate(var(--r))}}
.ohb-note p{margin:0;flex:1;font:13px/1.6 'Noto Serif SC',serif;color:#3B4659;overflow-wrap:anywhere}
.ohb-note small{margin-top:6px;font-size:10px;color:#55657B}
.ohb-pin{position:absolute;left:50%;top:-5px;width:13px;height:13px;margin-left:-6px;border-radius:50%;background:radial-gradient(circle at 35% 35%,#fff,#7FA7DC 55%,#4E78B0);box-shadow:0 2px 3px rgba(40,30,20,.4)}
.ohb-note.me .ohb-pin{background:radial-gradient(circle at 35% 35%,#fff,#F2B7C2 55%,#D88D9C)}
.ohb-pin.s{width:11px;height:11px;margin-left:-5px;background:radial-gradient(circle at 35% 35%,#fff,#E7B65C 55%,#B88A33)}
#companion-body .ohb-add{min-height:92px;border:1.5px dashed rgba(255,248,235,.8);border-radius:4px;background:rgba(70,45,20,.18);font:13px 'Noto Serif SC',serif;color:#FFFBF2;text-shadow:0 1px 2px rgba(70,45,20,.55);cursor:pointer}
.ohb-sec{margin:14px 2px 8px;font-size:10px;letter-spacing:.25em;color:#FFFBF2;text-shadow:0 1px 2px rgba(70,45,20,.55)}
.ohb-proms{display:flex;flex-direction:column;gap:10px}
.ohb-prom{position:relative;display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;padding:10px 12px 8px;background:#FFFDF7;box-shadow:0 3px 6px rgba(70,45,20,.28);transform:rotate(var(--r))}
.ohb-k{font-size:10px;color:#fff;background:#8F5428;border-radius:8px;padding:1px 7px}
.ohb-prom b{font:600 13px 'Noto Serif SC',serif;color:#2E3A4F}
.ohb-prom small{width:100%;font-size:10px;color:#5F6E84}
.ohb .oh-pop-dim{border-radius:18px}
@media (prefers-reduced-motion:reduce){.ohc.flip .ohc-art,.ohc.flip .ohc-grid,.ohc.flip .ohc-memo,.ohb-note{animation:none}}

/* ===== 记忆罐、花、空调 (js/apps/offline-home-jar.js): the jar and the flower are glass dialogs (.ohj), the 空调 is a remote in a transparent one (.oha). The wind and the falling stars live in the fx layer. ===== */
#companion-body .oh-root .oh-sheet.glass.ohj-sheet{max-width:320px}
#companion-body .oh-root .oh-sheet.glass.oha-sheet{padding:0;background:transparent;border:0;box-shadow:none;backdrop-filter:none;-webkit-backdrop-filter:none;overflow:visible;max-height:none;max-width:250px;width:calc(100% - 28px)}
#companion-body .oh-sheet.glass.oha-sheet .oh-close{right:-6px;top:-12px;z-index:13;background:var(--gl);border:1px solid var(--gle);border-radius:50%;min-width:38px;min-height:38px;font-size:18px;color:var(--gi);backdrop-filter:blur(14px)}

/* 记忆罐 */
.ohj-h{display:flex;align-items:baseline;gap:8px;margin:0 36px 4px 2px}
.ohj-h b{font:600 17px 'Noto Serif SC',serif;color:var(--gi)}
.ohj-h span{font-size:11px;color:var(--gi2)}
.ohj-stage{position:relative;height:120px;display:flex;align-items:flex-end;justify-content:center}
#companion-body .ohj-jar{background:none;border:0;padding:0;cursor:pointer;transform-origin:50% 100%}
.ohj-jar img,.ohj-fhero img{image-rendering:pixelated;display:block}
.ohj-jar.shake{animation:ohjShake .5s ease-in-out}
@keyframes ohjShake{20%{transform:rotate(-7deg)}40%{transform:rotate(6deg)}60%{transform:rotate(-4deg)}80%{transform:rotate(2deg)}}
.ohj-star{position:absolute;left:50%;bottom:62px;width:18px;height:18px;margin-left:-9px;background:var(--c,#b9add3);clip-path:polygon(50% 0,61% 35%,98% 35%,68% 57%,79% 91%,50% 70%,21% 91%,32% 57%,2% 35%,39% 35%);opacity:0;pointer-events:none;filter:drop-shadow(0 0 4px rgba(255,255,255,.9))}
.ohj-star.pop{animation:ohjPop .7s cubic-bezier(.3,1.4,.5,1) forwards}
@keyframes ohjPop{0%{opacity:1;transform:translateY(0) scale(.6)}55%{opacity:1;transform:translateY(-46px) scale(1.25) rotate(40deg)}100%{opacity:0;transform:translateY(-30px) scale(.4) rotate(80deg)}}
.ohj-card{min-height:118px;margin-top:10px;opacity:0;transform:translateY(6px)}
.ohj-card.show{opacity:1;transform:none;transition:opacity .25s,transform .25s}
.ohj-hint{text-align:center;font-size:12px;color:var(--gi2);padding-top:40px}
.ohj-mem{border-radius:16px;background:#FFFDF7;box-shadow:inset 0 0 0 1px rgba(160,170,190,.2),inset 4px 0 0 var(--c);padding:12px 14px 10px 18px}
.ohj-top{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.ohj-kind{font-size:11px;color:#2E3A4F;background:var(--c);border-radius:9px;padding:2px 8px}
.ohj-new{font-size:10px;color:#B8394F;border:1px solid rgba(184,57,79,.5);border-radius:9px;padding:1px 6px}
.ohj-flag{font-size:10px;color:#55657B;background:rgba(46,58,79,.06);border-radius:9px;padding:2px 7px}
.ohj-top em{margin-left:auto;font-style:normal;font-size:10px;color:#55657B}
.ohj-mem p{margin:8px 0 6px;font:14px/1.7 'Noto Serif SC',serif;color:#2E3A4F;overflow-wrap:anywhere}
#companion-body .ohj-open{border:0;background:none;padding:6px 0;min-height:32px;font-size:11px;color:#3F74BF;cursor:pointer}
.ohj-ca{margin-top:12px}
#companion-body .ohj-ca button,#companion-body .ohj-fa button{width:100%;min-height:42px;border:0;border-radius:21px;background:rgba(46,58,79,.07);font:14px 'Noto Serif SC',serif;color:var(--gi);cursor:pointer}
#companion-body .ohj-ca button.p,#companion-body .ohj-fa button.p{background:#3F74BF;color:#fff}
.ohj-fall{position:absolute;background:var(--c);clip-path:polygon(50% 0,61% 35%,98% 35%,68% 57%,79% 91%,50% 70%,21% 91%,32% 57%,2% 35%,39% 35%);pointer-events:none;z-index:40;opacity:0;animation:ohjFall 1s cubic-bezier(.5,0,.7,1) forwards}
@keyframes ohjFall{0%{opacity:.9;transform:translateY(0) rotate(0)}15%{opacity:1}85%{opacity:1}100%{opacity:.9;transform:translateY(var(--fy)) rotate(160deg) scale(.6)}}
.ohj-flash{position:absolute;border-radius:50%;background:radial-gradient(circle,rgba(255,244,200,.95),rgba(255,244,200,0) 70%);pointer-events:none;z-index:40;animation:ohjFlash .6s ease-out both}
@keyframes ohjFlash{0%{opacity:0;transform:scale(.4)}40%{opacity:1}100%{opacity:0;transform:scale(1.6)}}

/* 花 */
.ohj-fhero{display:flex;justify-content:center;align-items:flex-end;height:170px}
.ohj-bar{display:flex;gap:6px;margin:10px 0 0}
.ohj-seg{flex:1;text-align:center}
.ohj-seg i{display:block;height:6px;border-radius:3px;background:rgba(46,58,79,.1)}
.ohj-seg.past i{background:rgba(63,116,191,.35)}
.ohj-seg.on i{background:#3F74BF}
.ohj-seg b{display:block;margin-top:5px;font:600 11.5px 'Noto Serif SC',serif;color:var(--gi2)}
.ohj-seg.on b{color:var(--gi)}
.ohj-seg small{display:block;font-size:9.5px;color:var(--gi2)}
.ohj-fcard{margin-top:12px;padding:12px 14px;border-radius:6px;background:#FFFDF7;box-shadow:0 4px 12px rgba(40,60,90,.14);transform:rotate(-1.2deg)}
.ohj-fcard p{margin:0;font:14px/1.7 'Noto Serif SC',serif;color:#3B4659;overflow-wrap:anywhere}
.ohj-fcard small{display:block;text-align:right;margin-top:4px;font-size:10.5px;color:#55657B}
.ohj-fa{display:flex;gap:8px;margin-top:14px}

/* 空调 */
.oha-remote{border-radius:30px 30px 40px 40px;padding:18px 16px 20px;background:linear-gradient(180deg,#FBFCFE,#E6EBF2);box-shadow:0 18px 40px rgba(40,60,90,.3),inset 0 2px 0 #fff,inset 0 -3px 0 rgba(120,140,165,.25)}
.oha-lcd{border-radius:12px;padding:10px 12px 8px;background:#C9D2C4;box-shadow:inset 0 2px 5px rgba(40,60,40,.25);color:rgba(40,52,40,.75);transition:color .2s,background .2s}
.oha-lcd.on{background:#CFE0D0;color:#2E3D30}
.oha-l1{display:flex;justify-content:space-between;gap:8px;font-size:10.5px;letter-spacing:.04em}
.oha-l2{display:flex;align-items:flex-start;justify-content:center;margin-top:2px}
.oha-l2 b{font:600 44px/1.05 'Noto Serif SC',serif;letter-spacing:-.02em}
.oha-l2 i{font-style:normal;font-size:13px;margin-top:6px}
.oha-row{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-top:12px}
#companion-body .oha-k{flex:1;min-height:42px;border:0;border-radius:21px;background:#fff;box-shadow:0 2px 0 rgba(120,140,165,.35),0 3px 8px rgba(40,60,90,.1);font:600 13px 'Noto Serif SC',serif;color:#3B4659;cursor:pointer}
.oha-k:active{transform:translateY(1px);box-shadow:0 1px 0 rgba(120,140,165,.35)}
#companion-body .oha-k.on{background:#3F74BF;color:#fff}
#companion-body .oha-k.pw.on{background:rgba(46,58,79,.12);color:#3B4659}
.oha-k:disabled{opacity:.4;cursor:default}
#companion-body .oha-row .oha-k[data-m=up],#companion-body .oha-row .oha-k[data-m=down]{flex:none;width:56px;font-size:18px}
.oha-lab{font-size:11px;color:#55657B;letter-spacing:.2em}
.oha-credit{margin:10px auto 0;width:max-content;max-width:100%;padding:3px 10px;border-radius:10px;background:rgba(255,255,255,.88);font-size:10px;color:#55657B;text-align:center}
.ohj-wind{position:absolute;pointer-events:none;border-radius:50%;border-bottom:2px solid rgba(255,255,255,.95);filter:drop-shadow(0 0 1px rgba(70,120,180,.8));opacity:0;animation:ohjWind 2.2s ease-out both}
.ohj-wind.heat{border-bottom-color:rgba(238,150,80,.9);filter:drop-shadow(0 0 1px rgba(170,100,50,.7))}
@keyframes ohjWind{0%{opacity:0;transform:translateY(0) scaleX(.6)}25%{opacity:.95}100%{opacity:0;transform:translateY(var(--fy)) scaleX(1.4)}}
@media (prefers-reduced-motion:reduce){.ohj-jar.shake,.ohj-star.pop,.ohj-fall,.ohj-flash,.ohj-wind{animation:none}}
