/* ── Retro UI kit tokens (uiCookies) — identical in every set ─────────────
A classic desktop OS look: grey bevelled faces, navy title bars, sunken white fields on a dithered teal desktop.
Bevels are four 1px inset shadows built from --retro-hilite, --retro-light, --retro-shadow and --retro-dark,
so one change to a token re-colours every button, field and window in the kit. */
:root{
--retro-desk:#006e6e; /* desktop behind the windows */
--retro-desk-text:#ffffff; /* captions and icon labels on the desktop, 6.1:1 */
--retro-desk-dither:rgba(0,0,0,.22);
--retro-face:#c0c0c0; /* window, button and bar faces */
--retro-hilite:#ffffff; /* bevel: outer light edge */
--retro-light:#dfdfdf; /* bevel: inner light edge */
--retro-shadow:#808080; /* bevel: inner dark edge */
--retro-dark:#0a0a0a; /* bevel: outer dark edge */
--retro-text:#000000; /* text on faces, 11.5:1 */
--retro-muted:#3d3d3d; /* secondary text on faces, 6:1 */
--retro-field:#ffffff; /* inputs, lists and document areas */
--retro-field-text:#000000;
--retro-title:#000080; /* active title bar gradient, white text 6.3:1 or more */
--retro-title-2:#1060b0;
--retro-title-text:#ffffff;
--retro-idle:#5a5a5a; /* inactive title bar gradient, white text 5.3:1 or more */
--retro-idle-2:#6b6b6b;
--retro-idle-text:#ffffff;
--retro-select:#000080; /* highlighted menu items, rows and dates */
--retro-select-text:#ffffff;
--retro-link:#0000cc; /* 6.2:1 on faces */
--retro-danger:#8a0000; /* error text, 5.5:1 on faces */
--retro-tip:#ffffe1; /* tooltips and balloons */
--retro-tip-text:#000000;
--retro-tip-line:#000000;
--retro-lcd:#0b1a0b; /* LCD read-outs */
--retro-lcd-text:#4dff4d;
--retro-accent:#000080; /* progress chunks */
--retro-disabled:#808080; /* disabled text, embossed */
--retro-emboss:#ffffff;
--retro-dither-a:#ffffff; /* checkerboard behind a latched toggle */
--retro-dither-b:#c0c0c0;
--retro-focus:#000000; /* dotted focus rectangle */
--retro-glow:0 0 #0000; /* the synthwave theme adds a neon glow to windows */
--retro-neon-pink:#ff3fa4;--retro-neon-cyan:#00e5ff;--retro-sun-1:#ffd23f;--retro-sun-2:#ff3fa4;
--retro-font:Tahoma,"Microsoft Sans Serif","MS Sans Serif",Geneva,Verdana,"Segoe UI",sans-serif;
--retro-mono:"VT323","Fixedsys","Lucida Console",Consolas,Menlo,"Courier New",ui-monospace,monospace;
}
/* Synthwave 80s night theme: data-retro="synthwave" on any wrapper, or a checked .retro-theme-input inside a
[data-retro] element. :is() is a forgiving list, so browsers without :has() still apply the attribute. */
[data-retro]:is([data-retro="synthwave"],:has(.retro-theme-input:checked)){
--retro-desk:#14062b;--retro-desk-text:#fff1fb;--retro-desk-dither:rgba(255,63,164,.16);
--retro-face:#261047;--retro-hilite:#ff6ec7;--retro-light:#a05cff;--retro-shadow:#0d0420;--retro-dark:#000000;
--retro-text:#fff1fb;--retro-muted:#dcc6ff;--retro-field:#0e0322;--retro-field-text:#fff1fb;
--retro-title:#ff8a3d;--retro-title-2:#ff3fa4;--retro-title-text:#1b0030;
--retro-idle:#4a2d6e;--retro-idle-2:#5c3a85;--retro-idle-text:#f3e8ff;
--retro-select:#00e5ff;--retro-select-text:#14062b;--retro-link:#7cf3ff;--retro-danger:#ff8fa3;
--retro-tip:#2b1352;--retro-tip-text:#fff1fb;--retro-tip-line:#ff6ec7;
--retro-lcd:#07010f;--retro-lcd-text:#ff5fd2;--retro-accent:#ff3fa4;
--retro-disabled:#8a72b0;--retro-emboss:transparent;--retro-dither-a:#3d1a6e;--retro-dither-b:#261047;
--retro-focus:#5ff4ff;--retro-glow:0 0 0 1px rgba(255,63,164,.45),0 0 22px rgba(255,63,164,.35);color-scheme:dark}
/* More contrast requested: secondary text turns full strength and the glow goes */
@media (prefers-contrast:more){:root,[data-retro],[data-retro]:is([data-retro="synthwave"],:has(.retro-theme-input:checked)){--retro-muted:var(--retro-text);--retro-glow:0 0 #0000}}
:root,[data-retro]{
--retro-out:inset -1px -1px var(--retro-dark),inset 1px 1px var(--retro-hilite),inset -2px -2px var(--retro-shadow),inset 2px 2px var(--retro-light);
--retro-in:inset -1px -1px var(--retro-hilite),inset 1px 1px var(--retro-dark),inset -2px -2px var(--retro-light),inset 2px 2px var(--retro-shadow);
--retro-out-default:inset 0 0 0 1px var(--retro-dark),inset -2px -2px var(--retro-dark),inset 2px 2px var(--retro-hilite),inset -3px -3px var(--retro-shadow),inset 3px 3px var(--retro-light);
--retro-in-default:inset 0 0 0 1px var(--retro-dark),inset 2px 2px var(--retro-shadow),inset -2px -2px var(--retro-shadow);
--retro-sunken:inset -1px -1px var(--retro-hilite),inset 1px 1px var(--retro-shadow),inset -2px -2px var(--retro-light),inset 2px 2px var(--retro-dark);
--retro-frame:inset -1px -1px var(--retro-dark),inset 1px 1px var(--retro-light),inset -2px -2px var(--retro-shadow),inset 2px 2px var(--retro-hilite);
--retro-window:var(--retro-frame),var(--retro-glow);
--retro-thin-in:inset -1px -1px var(--retro-hilite),inset 1px 1px var(--retro-shadow);
--retro-thin-out:inset -1px -1px var(--retro-shadow),inset 1px 1px var(--retro-hilite);
--retro-title-bg:linear-gradient(90deg,var(--retro-title),var(--retro-title-2));
--retro-idle-bg:linear-gradient(90deg,var(--retro-idle),var(--retro-idle-2));
--retro-dither:repeating-conic-gradient(var(--retro-dither-a) 0 25%,var(--retro-dither-b) 0 50%) 0 0/2px 2px;
--retro-wallpaper:radial-gradient(var(--retro-desk-dither) 1px,transparent 1.5px) 0 0/4px 4px,var(--retro-desk);
--retro-check-mask:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%207%207'%20shape-rendering='crispEdges'%3E%3Crect%20x='6'%20y='0'%20width='1'%20height='1'%20fill='%23000'/%3E%3Crect%20x='5'%20y='1'%20width='2'%20height='1'%20fill='%23000'/%3E%3Crect%20x='0'%20y='2'%20width='1'%20height='1'%20fill='%23000'/%3E%3Crect%20x='4'%20y='2'%20width='3'%20height='1'%20fill='%23000'/%3E%3Crect%20x='0'%20y='3'%20width='2'%20height='1'%20fill='%23000'/%3E%3Crect%20x='3'%20y='3'%20width='3'%20height='1'%20fill='%23000'/%3E%3Crect%20x='0'%20y='4'%20width='5'%20height='1'%20fill='%23000'/%3E%3Crect%20x='1'%20y='5'%20width='3'%20height='1'%20fill='%23000'/%3E%3Crect%20x='2'%20y='6'%20width='1'%20height='1'%20fill='%23000'/%3E%3C/svg%3E");
--retro-arrow-mask:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%207%204'%20shape-rendering='crispEdges'%3E%3Crect%20x='0'%20y='0'%20width='7'%20height='1'%20fill='%23000'/%3E%3Crect%20x='1'%20y='1'%20width='5'%20height='1'%20fill='%23000'/%3E%3Crect%20x='2'%20y='2'%20width='3'%20height='1'%20fill='%23000'/%3E%3Crect%20x='3'%20y='3'%20width='1'%20height='1'%20fill='%23000'/%3E%3C/svg%3E");
}
[data-retro]{color:var(--retro-text);font-family:var(--retro-font)}
/* Components */
:where([class*="retro-"]),:where([class*="retro-"])::before,:where([class*="retro-"])::after{box-sizing:border-box}
.retro-sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
.retro-ico{display:block;flex:none;width:16px;height:16px;shape-rendering:crispEdges}
.retro-ico--md{width:24px;height:24px}
.retro-ico--lg{width:32px;height:32px}
.retro-glyph{display:block;flex:none;shape-rendering:crispEdges}
.retro-link{color:var(--retro-link);text-decoration:underline;text-underline-offset:2px}
.retro-link:hover{color:var(--retro-link);text-decoration-thickness:2px}
.retro-link:focus-visible{outline:2px dotted var(--retro-focus);outline-offset:2px}
.retro-muted{color:var(--retro-muted)}
.retro-cluster{display:flex;flex-wrap:wrap;align-items:center;gap:10px}
.retro-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,250px),1fr));gap:24px;align-items:start}
.retro-stack{display:grid;gap:10px}
/* Push buttons: raised bevel; pressing swaps it for the sunken one. The default button gets an extra dark frame */
.retro-btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;min-width:88px;min-height:32px;margin:0;padding:5px 14px;border:0;border-radius:0;
background:var(--retro-face);color:var(--retro-text);box-shadow:var(--retro-out);font:400 .875rem/1.2 var(--retro-font);text-align:center;text-decoration:none;cursor:pointer}
.retro-btn:hover{color:var(--retro-text)}
.retro-btn:active:not(:disabled){box-shadow:var(--retro-in)}
.retro-btn:focus-visible{outline:2px dotted var(--retro-focus);outline-offset:-6px}
.retro-btn--default{box-shadow:var(--retro-out-default);font-weight:700}
.retro-btn--default:active:not(:disabled){box-shadow:var(--retro-in-default)}
.retro-btn--sm{min-width:0;min-height:26px;padding:3px 10px;font-size:.8125rem}
.retro-btn--lg{min-height:42px;padding:8px 22px;font-size:1rem;font-weight:700}
.retro-btn--block{width:100%}
.retro-btn:disabled{color:var(--retro-disabled);text-shadow:1px 1px 0 var(--retro-emboss);cursor:default}
.retro-btn:disabled .retro-ico{opacity:.5}
/* Checkboxes and radio buttons: real inputs with appearance:none, a sunken white well and a pixel tick or dot.
Focus draws the classic dotted rectangle round the label text */
.retro-check{display:inline-flex;align-items:center;gap:8px;min-height:24px;margin:0;color:var(--retro-text);font:400 .875rem/1.3 var(--retro-font);cursor:pointer}
.retro-check__box{appearance:none;display:grid;place-content:center;flex:none;width:16px;height:16px;margin:0;border:0;border-radius:0;
background:var(--retro-field);box-shadow:var(--retro-sunken);cursor:pointer}
.retro-check__box::before{content:"";width:10px;height:10px;background:var(--retro-field-text);
-webkit-mask:var(--retro-check-mask) center/contain no-repeat;mask:var(--retro-check-mask) center/contain no-repeat;scale:0}
.retro-check__box[type="radio"]{border-radius:50%}
.retro-check__box[type="radio"]::before{width:6px;height:6px;border-radius:50%;-webkit-mask:none;mask:none}
.retro-check__box:checked::before{scale:1}
.retro-check__box:focus-visible{outline:0}
.retro-check__box:focus-visible+span{outline:2px dotted var(--retro-focus);outline-offset:1px}
.retro-check__box:disabled{background:var(--retro-face);cursor:default}
.retro-check__box:disabled::before{background:var(--retro-disabled)}
.retro-check__box:disabled+span{color:var(--retro-disabled);text-shadow:1px 1px 0 var(--retro-emboss)}
/* Window: a bevelled frame, a gradient title bar with labelled controls, a body and an optional status bar */
.retro-window{display:flex;flex-direction:column;min-width:0;padding:3px;background:var(--retro-face);color:var(--retro-text);box-shadow:var(--retro-window);font:400 .875rem/1.4 var(--retro-font)}
.retro-window :where(h2,h3,h4,p,ul,ol,dl,dd,figure){margin:0}
.retro-titlebar{display:flex;align-items:center;gap:6px;min-height:28px;padding:2px 3px 2px 5px;background:var(--retro-title-bg);color:var(--retro-title-text)}
.retro-titlebar--idle{background:var(--retro-idle-bg);color:var(--retro-idle-text)}
.retro-titlebar__title{display:flex;align-items:center;gap:6px;flex:1;min-width:0;margin:0;color:inherit;font:700 .875rem/1.2 var(--retro-font)}
.retro-titlebar__title span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.retro-titlebar__controls{display:flex;flex:none;gap:2px}
.retro-ctl{display:grid;place-items:center;width:24px;height:22px;margin:0;padding:0;border:0;border-radius:0;background:var(--retro-face);color:var(--retro-text);box-shadow:var(--retro-out);cursor:pointer}
.retro-ctl:active{box-shadow:var(--retro-in)}
.retro-ctl:focus-visible{outline:2px dotted var(--retro-focus);outline-offset:-5px}
.retro-ctl--close{margin-left:2px}
.retro-window__body{padding:12px 10px}
.retro-statusbar{display:flex;flex-wrap:wrap;gap:2px;margin-top:2px}
.retro-statusbar>*{flex:1 1 auto;padding:3px 7px;box-shadow:var(--retro-thin-in);font-size:.8125rem}
/* Fields: sunken wells. Errors add a red frame, an icon and a message tied to the field */
.retro-label{display:block;margin:0 0 4px;color:var(--retro-text);font:400 .875rem/1.3 var(--retro-font)}
.retro-input{display:block;width:100%;min-height:30px;margin:0;padding:5px 7px;border:0;border-radius:0;background:var(--retro-field);color:var(--retro-field-text);
box-shadow:var(--retro-sunken);font:400 .875rem/1.3 var(--retro-font)}
.retro-input::placeholder{color:var(--retro-muted);opacity:1}
.retro-input:focus{outline:0}
.retro-input:focus-visible{outline:2px dotted var(--retro-focus);outline-offset:2px}
.retro-input:disabled{background:var(--retro-face);color:var(--retro-disabled)}
.retro-input[aria-invalid="true"]{box-shadow:var(--retro-sunken),0 0 0 2px var(--retro-danger)}
textarea.retro-input{min-height:96px;resize:vertical;scrollbar-color:var(--retro-shadow) var(--retro-face)}
.retro-hint{margin:4px 0 0;color:var(--retro-muted);font-size:.8125rem}
.retro-error{display:flex;align-items:flex-start;gap:6px;margin:6px 0 0;color:var(--retro-danger);font-size:.8125rem;font-weight:700}
.retro-select{position:relative;display:block}
.retro-select select{appearance:none;cursor:pointer;padding-right:34px}
.retro-select::before{content:"";position:absolute;top:2px;right:2px;bottom:2px;width:24px;background:var(--retro-face);box-shadow:var(--retro-out);pointer-events:none}
.retro-select::after{content:"";position:absolute;top:50%;right:10px;width:7px;height:4px;margin-top:-2px;background:var(--retro-text);
-webkit-mask:var(--retro-arrow-mask) center/contain no-repeat;mask:var(--retro-arrow-mask) center/contain no-repeat;pointer-events:none}
.retro-select option,.retro-list option{background:var(--retro-field);color:var(--retro-field-text)}
.retro-list{display:block;width:100%;margin:0;padding:3px;border:0;border-radius:0;background:var(--retro-field);color:var(--retro-field-text);box-shadow:var(--retro-sunken);
font:400 .875rem/1.3 var(--retro-font);scrollbar-color:var(--retro-shadow) var(--retro-face)}
.retro-list option{padding:3px 6px}
.retro-list option:checked{background:var(--retro-select) linear-gradient(var(--retro-select),var(--retro-select));color:var(--retro-select-text)}
.retro-list:focus{outline:0}
.retro-list:focus-visible{outline:2px dotted var(--retro-focus);outline-offset:2px}
/* Trackbar: a native range input with a sunken groove and a raised rectangular thumb */
.retro-range{display:block;width:100%;height:28px;margin:0;background:transparent;appearance:none;cursor:pointer}
.retro-range::-webkit-slider-runnable-track{height:6px;background:var(--retro-field);box-shadow:var(--retro-sunken)}
.retro-range::-moz-range-track{height:6px;background:var(--retro-field);box-shadow:var(--retro-sunken)}
.retro-range::-webkit-slider-thumb{width:12px;height:22px;margin-top:-8px;border:0;border-radius:0;background:var(--retro-face);box-shadow:var(--retro-out);appearance:none}
.retro-range::-moz-range-thumb{width:12px;height:22px;border:0;border-radius:0;background:var(--retro-face);box-shadow:var(--retro-out)}
.retro-range:focus{outline:0}
.retro-range:focus-visible{outline:2px dotted var(--retro-focus);outline-offset:2px}
.retro-scale{display:flex;justify-content:space-between;margin-top:2px;color:var(--retro-muted);font-size:.8125rem}
/* Menu bar and drop-down menus (disclosure buttons and lists of links or buttons) */
.retro-menubar{display:flex;flex-wrap:wrap;margin:0;padding:1px 0;list-style:none}
.retro-menubar>li{position:relative}
.retro-menubar__btn{display:block;margin:0;padding:4px 9px;border:0;border-radius:0;background:transparent;color:var(--retro-text);font:400 .875rem/1.3 var(--retro-font);cursor:pointer}
.retro-menubar__btn:hover,.retro-menubar__btn[aria-expanded="true"],.retro-menubar__btn:focus-visible{background:var(--retro-select);color:var(--retro-select-text)}
.retro-menubar__btn:focus-visible{outline:2px dotted var(--retro-select-text);outline-offset:-3px}
.retro-menu{position:absolute;top:100%;left:0;z-index:20;min-width:210px;margin:0;padding:3px;list-style:none;background:var(--retro-face);box-shadow:var(--retro-frame),2px 2px 0 rgba(0,0,0,.4)}
.retro-menu[hidden]{display:none}
.retro-menu__item{display:flex;align-items:center;gap:8px;width:100%;margin:0;padding:5px 12px 5px 8px;border:0;border-radius:0;background:transparent;color:var(--retro-text);
font:400 .875rem/1.3 var(--retro-font);text-align:left;text-decoration:none;white-space:nowrap;cursor:pointer}
.retro-menu__item:hover,.retro-menu__item:focus-visible{background:var(--retro-select);color:var(--retro-select-text)}
.retro-menu__item:focus-visible{outline:2px dotted var(--retro-select-text);outline-offset:-3px}
.retro-menu__mark{display:grid;place-items:center;width:14px;flex:none}
.retro-menu__key{margin-left:auto;padding-left:22px}
.retro-menu__sep{height:2px;margin:3px 2px;box-shadow:inset 0 1px var(--retro-shadow),inset 0 -1px var(--retro-hilite)}
/* Taskbar: Start button, window buttons (the active one is latched in) and a sunken tray */
.retro-taskbar{position:relative;display:flex;flex-wrap:wrap;align-items:center;gap:4px;padding:4px;background:var(--retro-face);box-shadow:inset 0 1px var(--retro-light),inset 0 2px var(--retro-hilite)}
.retro-start{min-width:0;padding:4px 10px 4px 6px;font-weight:700}
.retro-start[aria-expanded="true"]{box-shadow:var(--retro-in)}
.retro-taskbar__apps{display:flex;flex:1 1 220px;gap:4px;min-width:0;margin:0;padding:0;list-style:none}
.retro-taskbar__apps>li{display:flex;flex:0 1 180px;min-width:0}
.retro-taskbtn{justify-content:flex-start;width:100%;min-width:0}
.retro-taskbtn span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.retro-taskbtn[aria-pressed="true"]{box-shadow:var(--retro-in);background:var(--retro-dither);font-weight:700}
.retro-tray{display:flex;align-items:center;gap:8px;min-height:32px;margin-left:auto;padding:3px 10px;box-shadow:var(--retro-thin-in);font:400 .8125rem/1 var(--retro-font);white-space:nowrap}
/* Start menu: opens upwards from the Start button, with a vertical banner */
.retro-startwrap{position:relative}
.retro-startmenu{position:absolute;bottom:calc(100% + 6px);left:0;z-index:30;display:flex;min-width:240px;padding:3px;background:var(--retro-face);box-shadow:var(--retro-frame),2px 2px 0 rgba(0,0,0,.4)}
.retro-startmenu[hidden]{display:none}
.retro-startmenu__banner{display:flex;align-items:flex-end;padding:8px 5px;background:linear-gradient(0deg,var(--retro-title),var(--retro-title-2));color:var(--retro-title-text);
font:700 1.05rem/1 var(--retro-font);letter-spacing:.06em;writing-mode:vertical-rl;rotate:180deg}
.retro-startmenu__list{flex:1;margin:0;padding:0;list-style:none}
.retro-startmenu__list .retro-menu__item{gap:10px;padding:6px 14px 6px 8px}
/* Media player: an LCD screen, a seek trackbar, transport buttons and a playlist */
.retro-screen{display:grid;gap:6px;padding:10px 12px;background:var(--retro-lcd);color:var(--retro-lcd-text);box-shadow:var(--retro-sunken);font:400 1.2rem/1.1 var(--retro-mono)}
.retro-screen__row{display:flex;align-items:flex-end;justify-content:space-between;gap:12px}
.retro-screen__time{font-size:2.2rem;line-height:1;font-variant-numeric:tabular-nums}
.retro-eq{display:flex;align-items:flex-end;gap:3px;height:34px}
.retro-eq i{display:block;width:6px;height:var(--h);background:repeating-linear-gradient(0deg,var(--retro-lcd-text) 0 3px,transparent 3px 5px)}
.retro-transport{display:flex;flex-wrap:wrap;align-items:center;gap:4px;margin-top:10px}
.retro-transport .retro-btn,.retro-transport .btn-retro{min-width:40px;padding-inline:8px}
.retro-volume{display:flex;flex:1 1 140px;align-items:center;gap:6px;margin-left:auto;max-width:190px}
.retro-playlist{margin:10px 0 0;padding:3px;list-style:none;background:var(--retro-field);color:var(--retro-field-text);box-shadow:var(--retro-sunken);counter-reset:t}
.retro-playlist li{display:flex;gap:8px;padding:3px 6px;counter-increment:t}
.retro-playlist li::before{content:counter(t,decimal-leading-zero) "."}
.retro-playlist li span:last-child{margin-left:auto;font-variant-numeric:tabular-nums}
.retro-playlist [aria-current]{background:var(--retro-select);color:var(--retro-select-text)}
/* Message boxes: an icon, the message and centred buttons */
.retro-msg{display:flex;align-items:flex-start;gap:14px;padding:16px 14px 8px}
.retro-msg__text{display:grid;gap:6px;padding-top:4px}
.retro-actions--center{justify-content:center;padding:10px 12px 12px}
/* Native <dialog>: focus moves in, Tab stays inside and Escape closes it */
.retro-dialog{width:min(430px,calc(100vw - 32px));max-width:none;margin:auto;padding:0;border:0;background:transparent;color:var(--retro-text);overflow:visible}
.retro-dialog::backdrop{background:rgba(0,0,0,.45)}
.retro-dialog[open]{animation:retro-open .2s steps(4)}
@keyframes retro-open{from{clip-path:inset(0 100% 100% 0)}to{clip-path:inset(0)}}
/* File explorer: a folder tree of <details> and a file table, each in a sunken pane */
.retro-explorer{display:grid;grid-template-columns:minmax(150px,210px) minmax(0,1fr);gap:3px}
@media (max-width:640px){.retro-explorer{grid-template-columns:minmax(0,1fr)}}
.retro-pane{min-width:0;overflow:auto;padding:4px;background:var(--retro-field);color:var(--retro-field-text);box-shadow:var(--retro-sunken);font:400 .875rem/1.3 var(--retro-font)}
.retro-tree,.retro-tree ul{margin:0;padding:0;list-style:none}
.retro-tree ul{margin-left:8px;padding-left:10px;border-left:1px dotted var(--retro-muted)}
.retro-tree summary{display:flex;align-items:center;gap:5px;padding:2px 3px;cursor:pointer;list-style:none}
.retro-tree summary::-webkit-details-marker{display:none}
.retro-tree summary::before{content:"+";display:grid;place-items:center;flex:none;width:11px;height:11px;border:1px solid var(--retro-muted);background:var(--retro-field);color:var(--retro-field-text);font:700 11px/1 var(--retro-font)}
.retro-tree details[open]>summary::before{content:"\2212"}
.retro-tree a{display:flex;align-items:center;gap:5px;padding:2px 3px 2px 19px;color:inherit;text-decoration:none}
.retro-tree summary:focus-visible,.retro-tree a:focus-visible{outline:2px dotted var(--retro-focus);outline-offset:-1px}
.retro-tree [aria-current]{background:var(--retro-select);color:var(--retro-select-text)}
.retro-files{width:100%;border-collapse:collapse;color:var(--retro-field-text);font:400 .875rem/1.3 var(--retro-font)}
.retro-files th{padding:4px 8px;background:var(--retro-face);color:var(--retro-text);font-weight:400;text-align:left;box-shadow:var(--retro-out)}
.retro-files td{padding:3px 8px;white-space:nowrap}
.retro-files .num{text-align:right}
.retro-files a{display:inline-flex;align-items:center;gap:6px;color:inherit;text-decoration:none}
.retro-files tbody tr:hover td,.retro-files tbody tr:focus-within td{background:var(--retro-select);color:var(--retro-select-text)}
.retro-files a:focus-visible{outline:2px dotted currentColor;outline-offset:1px}
/* Desktop: icons, draggable windows and a taskbar with a classic / synthwave switch */
.retro-desktop{position:relative;display:flex;flex-direction:column;min-height:700px;overflow:hidden;background:var(--retro-wallpaper);box-shadow:var(--retro-window)}
.retro-desktop__area{position:relative;flex:1;min-height:640px;isolation:isolate}
.retro-desktop__icons{position:absolute;top:14px;left:10px;z-index:1;display:grid;gap:12px;margin:0;padding:0;list-style:none}
.retro-desk-icon{display:flex;flex-direction:column;align-items:center;gap:5px;width:86px;margin:0;padding:4px 2px;border:0;background:transparent;color:var(--retro-desk-text);font:400 .8125rem/1.2 var(--retro-font);text-align:center;cursor:pointer}
.retro-desk-icon span{padding:1px 4px;background:var(--retro-desk)}
.retro-desk-icon:hover span,.retro-desk-icon:focus-visible span{background:var(--retro-select);color:var(--retro-select-text)}
.retro-desk-icon:focus-visible{outline:2px dotted var(--retro-desk-text);outline-offset:1px}
.retro-desk-win{position:absolute;left:var(--x);top:var(--y);z-index:2;width:var(--w);max-width:calc(100% - 16px)}
.retro-desk-win[hidden]{display:none}
.retro-titlebar[data-idle]{background:var(--retro-idle-bg);color:var(--retro-idle-text)}
.retro-titlebar[data-drag]{cursor:move;touch-action:none;user-select:none}
.retro-mover{display:grid;place-items:center;width:22px;height:22px;margin:0;padding:0;border:0;background:transparent;color:inherit;cursor:move}
.retro-mover:focus-visible{outline:2px dotted currentColor;outline-offset:-1px}
.retro-desktop .retro-taskbar{position:relative;z-index:5}
.retro-taskbar__apps>li[hidden]{display:none}
.retro-desktop__floor,.retro-desktop__sun{display:none}
[data-retro]:is([data-retro="synthwave"],:has(.retro-theme-input:checked)) :is(.retro-desktop__floor,.retro-desktop__sun){display:block}
.retro-desktop__floor{position:absolute;z-index:-1;left:-60%;right:-60%;top:58%;height:520px;transform:perspective(320px) rotateX(62deg);transform-origin:top;
background:repeating-linear-gradient(90deg,var(--retro-neon-pink) 0 2px,transparent 2px 64px),repeating-linear-gradient(0deg,var(--retro-neon-pink) 0 2px,transparent 2px 44px);opacity:.45;
-webkit-mask:linear-gradient(#000,transparent 85%);mask:linear-gradient(#000,transparent 85%)}
.retro-desktop__sun{position:absolute;z-index:-1;right:8%;top:calc(58% - 190px);width:240px;aspect-ratio:1;border-radius:50%;background:linear-gradient(var(--retro-sun-1),var(--retro-sun-2) 75%);box-shadow:0 0 60px rgba(255,63,164,.45);
-webkit-mask:linear-gradient(#000 50%,transparent 50% 54%,#000 54% 61%,transparent 61% 66%,#000 66% 72%,transparent 72% 78%,#000 78% 84%,transparent 84% 91%,#000 91%);
mask:linear-gradient(#000 50%,transparent 50% 54%,#000 54% 61%,transparent 61% 66%,#000 66% 72%,transparent 72% 78%,#000 78% 84%,transparent 84% 91%,#000 91%)}
@media (max-width:760px){.retro-desktop{min-height:0}.retro-desktop__area{display:grid;gap:16px;min-height:0;padding:12px}.retro-desktop__icons{position:static;display:flex;flex-wrap:wrap}
.retro-desk-win{position:static;width:auto;max-width:none}.retro-titlebar[data-drag]{cursor:default}}
.retro-btn--icon{min-width:40px;padding-inline:8px}
.retro-seek{margin-top:10px}
.retro-mailpane{max-height:210px}
.retro-notes{min-height:150px;resize:none}
@media (prefers-reduced-motion:reduce){[class*="retro-"],[class*="retro-"]::before,[class*="retro-"]::after{transition:none!important;animation:none!important}}
JavaScript
// Menus: a button opens its list; Escape, a click outside or opening another menu closes it.
// Arrow Down on a menu button opens it and focuses the first item; Arrow Up and Down move through the items.
(function () {
var toggles = Array.prototype.slice.call(document.querySelectorAll('[data-retro-menu]'));
function menuOf(b) { return document.getElementById(b.getAttribute('aria-controls')); }
function set(b, open) { b.setAttribute('aria-expanded', String(open)); menuOf(b).hidden = !open; }
function only(b, open) { toggles.forEach(function (o) { set(o, o === b ? open : false); }); }
toggles.forEach(function (b) {
var menu = menuOf(b);
b.addEventListener('click', function () { only(b, b.getAttribute('aria-expanded') !== 'true'); });
b.addEventListener('keydown', function (e) {
if (e.key !== 'ArrowDown') return;
e.preventDefault(); only(b, true);
var first = menu.querySelector('a, button'); if (first) first.focus();
});
menu.addEventListener('keydown', function (e) {
if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp') return;
e.preventDefault();
var items = Array.prototype.slice.call(menu.querySelectorAll('a, button'));
var i = items.indexOf(document.activeElement) + (e.key === 'ArrowDown' ? 1 : -1);
items[(i + items.length) % items.length].focus();
});
menu.addEventListener('click', function (e) { if (e.target.closest('a, button')) { set(b, false); b.focus(); } });
});
document.addEventListener('click', function (e) {
toggles.forEach(function (b) { if (!b.contains(e.target) && !menuOf(b).contains(e.target)) set(b, false); });
});
document.addEventListener('keydown', function (e) {
if (e.key !== 'Escape') return;
toggles.forEach(function (b) {
if (b.getAttribute('aria-expanded') !== 'true') return;
var inside = menuOf(b).contains(document.activeElement);
set(b, false); if (inside) b.focus();
});
});
})();
// Player: Play / Pause swaps the button's name and glyph; while playing the seek bar moves once a second.
// The seek bar's time read-out and aria-valuetext follow it as you drag or use the arrow keys.
document.querySelectorAll('[data-retro-player]').forEach(function (p) {
var seek = p.querySelector('[data-seek]'), out = p.querySelector('[data-time]'), play = p.querySelector('[data-play]');
var state = p.querySelector('[data-state]'), timer = null;
function fmt(s) { return String(Math.floor(s / 60)).padStart(2, '0') + ':' + String(s % 60).padStart(2, '0'); }
function words(s) { return Math.floor(s / 60) + ' min ' + (s % 60) + ' s'; }
function sync() {
var s = +seek.value;
out.textContent = fmt(s);
seek.setAttribute('aria-valuetext', words(s) + ' of ' + words(+seek.max));
}
function setPlaying(on) {
play.setAttribute('aria-label', on ? 'Pause' : 'Play');
play.querySelector('[data-icon="play"]').hidden = on;
play.querySelector('[data-icon="pause"]').hidden = !on;
if (state) state.textContent = on ? 'Playing' : 'Paused';
clearInterval(timer);
if (on) timer = setInterval(function () { seek.value = Math.min(+seek.value + 1, +seek.max); sync(); if (+seek.value >= +seek.max) setPlaying(false); }, 1000);
}
seek.addEventListener('input', sync);
play.addEventListener('click', function () { setPlaying(play.getAttribute('aria-label') === 'Play'); });
var stop = p.querySelector('[data-stop]');
if (stop) stop.addEventListener('click', function () { setPlaying(false); seek.value = 0; sync(); });
sync();
});
// Desktop: drag a window by its title bar, or focus its icon button and use the arrow keys (Shift moves further).
// Clicking or focusing a window brings it to the front; the taskbar shows which one is active.
(function () {
var desk = document.querySelector('[data-retro-desktop]'); if (!desk) return;
var area = desk.querySelector('[data-desk-area]');
var wins = Array.prototype.slice.call(desk.querySelectorAll('[data-win]'));
var z = 10;
function movable() { return window.matchMedia('(min-width: 761px)').matches; }
function task(win) { return desk.querySelector('[data-task="' + win.id + '"]'); }
function activate(win) {
wins.forEach(function (w) {
var on = w === win;
w.querySelector('[data-drag]').toggleAttribute('data-idle', !on);
var t = task(w); if (t) t.setAttribute('aria-pressed', String(on && !w.hidden));
});
win.style.zIndex = ++z;
}
function show(win) {
win.hidden = false;
var t = task(win); if (t) t.parentElement.hidden = false;
activate(win); win.querySelector('[data-move]').focus();
}
function place(win, x, y) {
x = Math.max(0, Math.min(x, area.clientWidth - win.offsetWidth));
y = Math.max(0, Math.min(y, area.clientHeight - win.offsetHeight));
win.style.left = x + 'px'; win.style.top = y + 'px';
}
wins.forEach(function (win) {
var bar = win.querySelector('[data-drag]'), mover = win.querySelector('[data-move]');
win.addEventListener('pointerdown', function () { activate(win); });
win.addEventListener('focusin', function () { activate(win); });
bar.addEventListener('pointerdown', function (e) {
if (e.button !== 0 || !movable() || e.target.closest('button:not([data-move])')) return;
var dx = e.clientX - win.offsetLeft, dy = e.clientY - win.offsetTop;
bar.setPointerCapture(e.pointerId);
function move(ev) { place(win, ev.clientX - dx, ev.clientY - dy); }
function up() { bar.removeEventListener('pointermove', move); bar.removeEventListener('pointerup', up); }
bar.addEventListener('pointermove', move); bar.addEventListener('pointerup', up);
});
mover.addEventListener('keydown', function (e) {
var d = { ArrowLeft: [-1, 0], ArrowRight: [1, 0], ArrowUp: [0, -1], ArrowDown: [0, 1] }[e.key];
if (!d || !movable()) return;
e.preventDefault();
var step = e.shiftKey ? 64 : 16;
place(win, win.offsetLeft + d[0] * step, win.offsetTop + d[1] * step);
});
win.querySelector('[data-min]').addEventListener('click', function () {
win.hidden = true;
var t = task(win); t.setAttribute('aria-pressed', 'false'); t.focus();
});
win.querySelector('[data-close]').addEventListener('click', function () {
win.hidden = true;
var t = task(win); if (t) t.parentElement.hidden = true;
var icon = desk.querySelector('[data-open="' + win.id + '"]'); if (icon) icon.focus();
});
});
desk.querySelectorAll('[data-task]').forEach(function (t) {
t.addEventListener('click', function () {
var win = document.getElementById(t.getAttribute('data-task'));
if (win.hidden) { show(win); return; }
if (t.getAttribute('aria-pressed') === 'true') { win.hidden = true; t.setAttribute('aria-pressed', 'false'); return; }
activate(win); win.querySelector('[data-move]').focus();
});
});
desk.querySelectorAll('[data-open]').forEach(function (b) {
b.addEventListener('click', function () { show(document.getElementById(b.getAttribute('data-open'))); });
});
var clock = desk.querySelector('[data-desk-clock]');
function tick() {
var d = new Date();
clock.textContent = d.toLocaleTimeString('en-GB', { hour: '2-digit', minute: '2-digit' });
clock.setAttribute('datetime', clock.textContent);
}
if (clock) { tick(); setInterval(tick, 15000); }
})();
/* ── Retro UI kit tokens (uiCookies) — identical in every set ─────────────
A classic desktop OS look: grey bevelled faces, navy title bars, sunken white fields on a dithered teal desktop.
Bevels are four 1px inset shadows built from --retro-hilite, --retro-light, --retro-shadow and --retro-dark,
so one change to a token re-colours every button, field and window in the kit. */
:root{
--retro-desk:#006e6e; /* desktop behind the windows */
--retro-desk-text:#ffffff; /* captions and icon labels on the desktop, 6.1:1 */
--retro-desk-dither:rgba(0,0,0,.22);
--retro-face:#c0c0c0; /* window, button and bar faces */
--retro-hilite:#ffffff; /* bevel: outer light edge */
--retro-light:#dfdfdf; /* bevel: inner light edge */
--retro-shadow:#808080; /* bevel: inner dark edge */
--retro-dark:#0a0a0a; /* bevel: outer dark edge */
--retro-text:#000000; /* text on faces, 11.5:1 */
--retro-muted:#3d3d3d; /* secondary text on faces, 6:1 */
--retro-field:#ffffff; /* inputs, lists and document areas */
--retro-field-text:#000000;
--retro-title:#000080; /* active title bar gradient, white text 6.3:1 or more */
--retro-title-2:#1060b0;
--retro-title-text:#ffffff;
--retro-idle:#5a5a5a; /* inactive title bar gradient, white text 5.3:1 or more */
--retro-idle-2:#6b6b6b;
--retro-idle-text:#ffffff;
--retro-select:#000080; /* highlighted menu items, rows and dates */
--retro-select-text:#ffffff;
--retro-link:#0000cc; /* 6.2:1 on faces */
--retro-danger:#8a0000; /* error text, 5.5:1 on faces */
--retro-tip:#ffffe1; /* tooltips and balloons */
--retro-tip-text:#000000;
--retro-tip-line:#000000;
--retro-lcd:#0b1a0b; /* LCD read-outs */
--retro-lcd-text:#4dff4d;
--retro-accent:#000080; /* progress chunks */
--retro-disabled:#808080; /* disabled text, embossed */
--retro-emboss:#ffffff;
--retro-dither-a:#ffffff; /* checkerboard behind a latched toggle */
--retro-dither-b:#c0c0c0;
--retro-focus:#000000; /* dotted focus rectangle */
--retro-glow:0 0 #0000; /* the synthwave theme adds a neon glow to windows */
--retro-neon-pink:#ff3fa4;--retro-neon-cyan:#00e5ff;--retro-sun-1:#ffd23f;--retro-sun-2:#ff3fa4;
--retro-font:Tahoma,"Microsoft Sans Serif","MS Sans Serif",Geneva,Verdana,"Segoe UI",sans-serif;
--retro-mono:"VT323","Fixedsys","Lucida Console",Consolas,Menlo,"Courier New",ui-monospace,monospace;
}
/* Synthwave 80s night theme: data-retro="synthwave" on any wrapper, or a checked .retro-theme-input inside a
[data-retro] element. :is() is a forgiving list, so browsers without :has() still apply the attribute. */
[data-retro]:is([data-retro="synthwave"],:has(.retro-theme-input:checked)){
--retro-desk:#14062b;--retro-desk-text:#fff1fb;--retro-desk-dither:rgba(255,63,164,.16);
--retro-face:#261047;--retro-hilite:#ff6ec7;--retro-light:#a05cff;--retro-shadow:#0d0420;--retro-dark:#000000;
--retro-text:#fff1fb;--retro-muted:#dcc6ff;--retro-field:#0e0322;--retro-field-text:#fff1fb;
--retro-title:#ff8a3d;--retro-title-2:#ff3fa4;--retro-title-text:#1b0030;
--retro-idle:#4a2d6e;--retro-idle-2:#5c3a85;--retro-idle-text:#f3e8ff;
--retro-select:#00e5ff;--retro-select-text:#14062b;--retro-link:#7cf3ff;--retro-danger:#ff8fa3;
--retro-tip:#2b1352;--retro-tip-text:#fff1fb;--retro-tip-line:#ff6ec7;
--retro-lcd:#07010f;--retro-lcd-text:#ff5fd2;--retro-accent:#ff3fa4;
--retro-disabled:#8a72b0;--retro-emboss:transparent;--retro-dither-a:#3d1a6e;--retro-dither-b:#261047;
--retro-focus:#5ff4ff;--retro-glow:0 0 0 1px rgba(255,63,164,.45),0 0 22px rgba(255,63,164,.35);color-scheme:dark}
/* More contrast requested: secondary text turns full strength and the glow goes */
@media (prefers-contrast:more){:root,[data-retro],[data-retro]:is([data-retro="synthwave"],:has(.retro-theme-input:checked)){--retro-muted:var(--retro-text);--retro-glow:0 0 #0000}}
:root,[data-retro]{
--retro-out:inset -1px -1px var(--retro-dark),inset 1px 1px var(--retro-hilite),inset -2px -2px var(--retro-shadow),inset 2px 2px var(--retro-light);
--retro-in:inset -1px -1px var(--retro-hilite),inset 1px 1px var(--retro-dark),inset -2px -2px var(--retro-light),inset 2px 2px var(--retro-shadow);
--retro-out-default:inset 0 0 0 1px var(--retro-dark),inset -2px -2px var(--retro-dark),inset 2px 2px var(--retro-hilite),inset -3px -3px var(--retro-shadow),inset 3px 3px var(--retro-light);
--retro-in-default:inset 0 0 0 1px var(--retro-dark),inset 2px 2px var(--retro-shadow),inset -2px -2px var(--retro-shadow);
--retro-sunken:inset -1px -1px var(--retro-hilite),inset 1px 1px var(--retro-shadow),inset -2px -2px var(--retro-light),inset 2px 2px var(--retro-dark);
--retro-frame:inset -1px -1px var(--retro-dark),inset 1px 1px var(--retro-light),inset -2px -2px var(--retro-shadow),inset 2px 2px var(--retro-hilite);
--retro-window:var(--retro-frame),var(--retro-glow);
--retro-thin-in:inset -1px -1px var(--retro-hilite),inset 1px 1px var(--retro-shadow);
--retro-thin-out:inset -1px -1px var(--retro-shadow),inset 1px 1px var(--retro-hilite);
--retro-title-bg:linear-gradient(90deg,var(--retro-title),var(--retro-title-2));
--retro-idle-bg:linear-gradient(90deg,var(--retro-idle),var(--retro-idle-2));
--retro-dither:repeating-conic-gradient(var(--retro-dither-a) 0 25%,var(--retro-dither-b) 0 50%) 0 0/2px 2px;
--retro-wallpaper:radial-gradient(var(--retro-desk-dither) 1px,transparent 1.5px) 0 0/4px 4px,var(--retro-desk);
--retro-check-mask:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%207%207'%20shape-rendering='crispEdges'%3E%3Crect%20x='6'%20y='0'%20width='1'%20height='1'%20fill='%23000'/%3E%3Crect%20x='5'%20y='1'%20width='2'%20height='1'%20fill='%23000'/%3E%3Crect%20x='0'%20y='2'%20width='1'%20height='1'%20fill='%23000'/%3E%3Crect%20x='4'%20y='2'%20width='3'%20height='1'%20fill='%23000'/%3E%3Crect%20x='0'%20y='3'%20width='2'%20height='1'%20fill='%23000'/%3E%3Crect%20x='3'%20y='3'%20width='3'%20height='1'%20fill='%23000'/%3E%3Crect%20x='0'%20y='4'%20width='5'%20height='1'%20fill='%23000'/%3E%3Crect%20x='1'%20y='5'%20width='3'%20height='1'%20fill='%23000'/%3E%3Crect%20x='2'%20y='6'%20width='1'%20height='1'%20fill='%23000'/%3E%3C/svg%3E");
--retro-arrow-mask:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%207%204'%20shape-rendering='crispEdges'%3E%3Crect%20x='0'%20y='0'%20width='7'%20height='1'%20fill='%23000'/%3E%3Crect%20x='1'%20y='1'%20width='5'%20height='1'%20fill='%23000'/%3E%3Crect%20x='2'%20y='2'%20width='3'%20height='1'%20fill='%23000'/%3E%3Crect%20x='3'%20y='3'%20width='1'%20height='1'%20fill='%23000'/%3E%3C/svg%3E");
}
[data-retro]{color:var(--retro-text);font-family:var(--retro-font)}
/* Bootstrap's own variables mapped onto the kit tokens */
:root,[data-retro]{--bs-body-bg:var(--retro-desk);--bs-body-color:var(--retro-text);--bs-body-font-family:var(--retro-font);--bs-emphasis-color:var(--retro-text);
--bs-secondary-color:var(--retro-muted);--bs-border-color:var(--retro-shadow);--bs-border-radius:0;--bs-border-radius-sm:0;--bs-border-radius-lg:0;
--bs-link-color:var(--retro-link);--bs-link-hover-color:var(--retro-link);--bs-focus-ring-color:var(--retro-focus)}
/* Components */
:where([class*="retro-"]),:where([class*="retro-"])::before,:where([class*="retro-"])::after{box-sizing:border-box}
.retro-sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
.retro-ico{display:block;flex:none;width:16px;height:16px;shape-rendering:crispEdges}
.retro-ico--md{width:24px;height:24px}
.retro-ico--lg{width:32px;height:32px}
.retro-glyph{display:block;flex:none;shape-rendering:crispEdges}
.retro-link{color:var(--retro-link);text-decoration:underline;text-underline-offset:2px}
.retro-link:hover{color:var(--retro-link);text-decoration-thickness:2px}
.retro-link:focus-visible{outline:2px dotted var(--retro-focus);outline-offset:2px}
.retro-muted{color:var(--retro-muted)}
.retro-cluster{display:flex;flex-wrap:wrap;align-items:center;gap:10px}
.retro-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,250px),1fr));gap:24px;align-items:start}
.retro-stack{display:grid;gap:10px}
/* Buttons: Bootstrap .btn with a .btn-retro variant set through --bs-btn-* variables */
.btn-retro{--bs-btn-padding-x:14px;--bs-btn-padding-y:5px;--bs-btn-font-family:var(--retro-font);--bs-btn-font-size:.875rem;--bs-btn-font-weight:400;--bs-btn-line-height:1.2;
--bs-btn-border-width:0;--bs-btn-border-radius:0;--bs-btn-bg:var(--retro-face);--bs-btn-color:var(--retro-text);--bs-btn-hover-bg:var(--retro-face);--bs-btn-hover-color:var(--retro-text);
--bs-btn-active-bg:var(--retro-face);--bs-btn-active-color:var(--retro-text);--bs-btn-disabled-bg:var(--retro-face);--bs-btn-disabled-color:var(--retro-disabled);--bs-btn-disabled-opacity:1;
display:inline-flex;align-items:center;justify-content:center;gap:6px;min-width:88px;min-height:32px;box-shadow:var(--retro-out)}
.btn-retro:active,.btn-retro.active,.btn-retro.show,.btn-check:checked+.btn-retro{box-shadow:var(--retro-in)}
.btn-retro:focus-visible,.btn-check:focus-visible+.btn-retro{box-shadow:var(--retro-out);outline:2px dotted var(--retro-focus);outline-offset:-6px}
.btn-check:checked:focus-visible+.btn-retro{box-shadow:var(--retro-in)}
.btn-retro:disabled{text-shadow:1px 1px 0 var(--retro-emboss)}
.btn-retro:disabled .retro-ico{opacity:.5}
.btn-retro-default{--bs-btn-font-weight:700;box-shadow:var(--retro-out-default)}
.btn-retro-default:focus-visible{box-shadow:var(--retro-out-default)}
.btn-retro-default:active{box-shadow:var(--retro-in-default)}
.btn-retro.btn-sm{--bs-btn-padding-x:10px;--bs-btn-padding-y:3px;--bs-btn-font-size:.8125rem;min-width:0;min-height:26px}
.btn-retro.btn-lg{--bs-btn-padding-x:22px;--bs-btn-padding-y:8px;--bs-btn-font-size:1rem;--bs-btn-font-weight:700;min-height:42px}
/* Checkboxes and radios: Bootstrap .form-check, with the input redrawn as a sunken well and a pixel tick */
.form-check.retro-fc{display:flex;align-items:center;gap:8px;min-height:24px;margin:0;padding:0;color:var(--retro-text);font:400 .875rem/1.3 var(--retro-font)}
.retro-fc .form-check-input{display:grid;place-content:center;flex:none;float:none;width:16px;height:16px;margin:0;border:0;border-radius:0;background:var(--retro-field);box-shadow:var(--retro-sunken);cursor:pointer}
.retro-fc .form-check-input:checked{background:var(--retro-field);background-image:none}
.retro-fc .form-check-input::before{content:"";width:10px;height:10px;background:var(--retro-field-text);
-webkit-mask:var(--retro-check-mask) center/contain no-repeat;mask:var(--retro-check-mask) center/contain no-repeat;scale:0}
.retro-fc .form-check-input[type="radio"]{border-radius:50%}
.retro-fc .form-check-input[type="radio"]::before{width:6px;height:6px;border-radius:50%;-webkit-mask:none;mask:none}
.retro-fc .form-check-input:checked::before{scale:1}
.retro-fc .form-check-input:focus{box-shadow:var(--retro-sunken);outline:0}
.retro-fc .form-check-input:focus-visible+.form-check-label{outline:2px dotted var(--retro-focus);outline-offset:1px}
.retro-fc .form-check-label{cursor:pointer}
.retro-fc .form-check-input:disabled{background:var(--retro-face);opacity:1}
.retro-fc .form-check-input:disabled::before{background:var(--retro-disabled)}
.retro-fc .form-check-input:disabled~.form-check-label{color:var(--retro-disabled);text-shadow:1px 1px 0 var(--retro-emboss);opacity:1}
/* Window: a bevelled frame, a gradient title bar with labelled controls, a body and an optional status bar */
.retro-window{display:flex;flex-direction:column;min-width:0;padding:3px;background:var(--retro-face);color:var(--retro-text);box-shadow:var(--retro-window);font:400 .875rem/1.4 var(--retro-font)}
.retro-window :where(h2,h3,h4,p,ul,ol,dl,dd,figure){margin:0}
.retro-titlebar{display:flex;align-items:center;gap:6px;min-height:28px;padding:2px 3px 2px 5px;background:var(--retro-title-bg);color:var(--retro-title-text)}
.retro-titlebar--idle{background:var(--retro-idle-bg);color:var(--retro-idle-text)}
.retro-titlebar__title{display:flex;align-items:center;gap:6px;flex:1;min-width:0;margin:0;color:inherit;font:700 .875rem/1.2 var(--retro-font)}
.retro-titlebar__title span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.retro-titlebar__controls{display:flex;flex:none;gap:2px}
.retro-ctl{display:grid;place-items:center;width:24px;height:22px;margin:0;padding:0;border:0;border-radius:0;background:var(--retro-face);color:var(--retro-text);box-shadow:var(--retro-out);cursor:pointer}
.retro-ctl:active{box-shadow:var(--retro-in)}
.retro-ctl:focus-visible{outline:2px dotted var(--retro-focus);outline-offset:-5px}
.retro-ctl--close{margin-left:2px}
.retro-window__body{padding:12px 10px}
.retro-statusbar{display:flex;flex-wrap:wrap;gap:2px;margin-top:2px}
.retro-statusbar>*{flex:1 1 auto;padding:3px 7px;box-shadow:var(--retro-thin-in);font-size:.8125rem}
/* Windows: Bootstrap .card with the header as a title bar */
.card.retro-window{--bs-card-bg:var(--retro-face);--bs-card-color:var(--retro-text);--bs-card-border-width:0;--bs-card-border-radius:0;--bs-card-inner-border-radius:0;
--bs-card-spacer-y:12px;--bs-card-spacer-x:10px;--bs-card-cap-padding-y:2px;--bs-card-cap-padding-x:5px;--bs-card-cap-bg:transparent;--bs-card-cap-color:var(--retro-title-text)}
.card-header.retro-titlebar{border-bottom:0;padding:2px 3px 2px 5px}
.card-header.retro-titlebar:first-child{border-radius:0}
.card-footer.retro-statusbar{padding:0;border-top:0;background:transparent}
.card-footer.retro-statusbar:last-child{border-radius:0}
.card-footer.retro-statusbar{color:var(--retro-text)}
/* Fields: sunken wells. Errors add a red frame, an icon and a message tied to the field */
.retro-label{display:block;margin:0 0 4px;color:var(--retro-text);font:400 .875rem/1.3 var(--retro-font)}
.retro-input{display:block;width:100%;min-height:30px;margin:0;padding:5px 7px;border:0;border-radius:0;background:var(--retro-field);color:var(--retro-field-text);
box-shadow:var(--retro-sunken);font:400 .875rem/1.3 var(--retro-font)}
.retro-input::placeholder{color:var(--retro-muted);opacity:1}
.retro-input:focus{outline:0}
.retro-input:focus-visible{outline:2px dotted var(--retro-focus);outline-offset:2px}
.retro-input:disabled{background:var(--retro-face);color:var(--retro-disabled)}
.retro-input[aria-invalid="true"]{box-shadow:var(--retro-sunken),0 0 0 2px var(--retro-danger)}
textarea.retro-input{min-height:96px;resize:vertical;scrollbar-color:var(--retro-shadow) var(--retro-face)}
.retro-hint{margin:4px 0 0;color:var(--retro-muted);font-size:.8125rem}
.retro-error{display:flex;align-items:flex-start;gap:6px;margin:6px 0 0;color:var(--retro-danger);font-size:.8125rem;font-weight:700}
.retro-select{position:relative;display:block}
.retro-select select{appearance:none;cursor:pointer;padding-right:34px}
.retro-select::before{content:"";position:absolute;top:2px;right:2px;bottom:2px;width:24px;background:var(--retro-face);box-shadow:var(--retro-out);pointer-events:none}
.retro-select::after{content:"";position:absolute;top:50%;right:10px;width:7px;height:4px;margin-top:-2px;background:var(--retro-text);
-webkit-mask:var(--retro-arrow-mask) center/contain no-repeat;mask:var(--retro-arrow-mask) center/contain no-repeat;pointer-events:none}
.retro-select option,.retro-list option{background:var(--retro-field);color:var(--retro-field-text)}
.retro-list{display:block;width:100%;margin:0;padding:3px;border:0;border-radius:0;background:var(--retro-field);color:var(--retro-field-text);box-shadow:var(--retro-sunken);
font:400 .875rem/1.3 var(--retro-font);scrollbar-color:var(--retro-shadow) var(--retro-face)}
.retro-list option{padding:3px 6px}
.retro-list option:checked{background:var(--retro-select) linear-gradient(var(--retro-select),var(--retro-select));color:var(--retro-select-text)}
.retro-list:focus{outline:0}
.retro-list:focus-visible{outline:2px dotted var(--retro-focus);outline-offset:2px}
/* Fields: Bootstrap .form-control and .form-select redrawn as sunken wells */
.form-control.retro-input,.form-select.retro-input{min-height:30px;padding:5px 7px;border:0;border-radius:0;background-color:var(--retro-field);color:var(--retro-field-text);box-shadow:var(--retro-sunken);font:400 .875rem/1.3 var(--retro-font)}
.form-control.retro-input:focus,.form-select.retro-input:focus{border:0;background-color:var(--retro-field);color:var(--retro-field-text);box-shadow:var(--retro-sunken)}
.form-control.retro-input[aria-invalid="true"]{box-shadow:var(--retro-sunken),0 0 0 2px var(--retro-danger)}
.form-control.retro-input:disabled{background:var(--retro-face);color:var(--retro-disabled)}
.form-select.retro-input{background-image:none;padding-right:34px}
textarea.form-control.retro-input{min-height:96px}
.form-select.retro-list,.form-select.retro-list[size]:not([size="1"]){padding:3px;border:0;border-radius:0;background-image:none;box-shadow:var(--retro-sunken)}
.form-select.retro-list:focus{border:0;box-shadow:var(--retro-sunken)}
.form-label.retro-label{margin-bottom:4px}
/* Trackbar: a native range input with a sunken groove and a raised rectangular thumb */
.retro-range{display:block;width:100%;height:28px;margin:0;background:transparent;appearance:none;cursor:pointer}
.retro-range::-webkit-slider-runnable-track{height:6px;background:var(--retro-field);box-shadow:var(--retro-sunken)}
.retro-range::-moz-range-track{height:6px;background:var(--retro-field);box-shadow:var(--retro-sunken)}
.retro-range::-webkit-slider-thumb{width:12px;height:22px;margin-top:-8px;border:0;border-radius:0;background:var(--retro-face);box-shadow:var(--retro-out);appearance:none}
.retro-range::-moz-range-thumb{width:12px;height:22px;border:0;border-radius:0;background:var(--retro-face);box-shadow:var(--retro-out)}
.retro-range:focus{outline:0}
.retro-range:focus-visible{outline:2px dotted var(--retro-focus);outline-offset:2px}
.retro-scale{display:flex;justify-content:space-between;margin-top:2px;color:var(--retro-muted);font-size:.8125rem}
.form-range.retro-range{height:28px}
.form-range.retro-range::-webkit-slider-thumb{width:12px;height:22px;margin-top:-8px;border:0;border-radius:0;background:var(--retro-face);box-shadow:var(--retro-out)}
.form-range.retro-range::-moz-range-thumb{width:12px;height:22px;border:0;border-radius:0;background:var(--retro-face);box-shadow:var(--retro-out)}
.form-range.retro-range::-webkit-slider-runnable-track{height:6px;border-radius:0;background:var(--retro-field);box-shadow:var(--retro-sunken)}
.form-range.retro-range::-moz-range-track{height:6px;border-radius:0;background:var(--retro-field);box-shadow:var(--retro-sunken)}
.form-range.retro-range:focus::-webkit-slider-thumb,.form-range.retro-range:focus::-moz-range-thumb{box-shadow:var(--retro-out)}
/* Drop-down menus: Bootstrap .dropdown-menu restyled through --bs-dropdown-* variables */
.retro-dd.dropdown-menu{--bs-dropdown-bg:var(--retro-face);--bs-dropdown-color:var(--retro-text);--bs-dropdown-border-width:0;--bs-dropdown-border-radius:0;--bs-dropdown-padding-x:3px;--bs-dropdown-padding-y:3px;
--bs-dropdown-spacer:0;--bs-dropdown-min-width:210px;--bs-dropdown-font-size:.875rem;--bs-dropdown-link-color:var(--retro-text);--bs-dropdown-link-hover-color:var(--retro-select-text);--bs-dropdown-link-hover-bg:var(--retro-select);
--bs-dropdown-link-active-color:var(--retro-select-text);--bs-dropdown-link-active-bg:var(--retro-select);--bs-dropdown-item-padding-x:8px;--bs-dropdown-item-padding-y:5px;--bs-dropdown-item-border-radius:0;
--bs-dropdown-divider-bg:transparent;--bs-dropdown-header-color:var(--retro-muted);--bs-dropdown-divider-margin-y:3px;box-shadow:var(--retro-frame),2px 2px 0 rgba(0,0,0,.4);font-family:var(--retro-font)}
.retro-dd .dropdown-item{display:flex;align-items:center;gap:8px;padding-right:12px;line-height:1.3}
.retro-dd .dropdown-item:focus-visible{background:var(--retro-select);color:var(--retro-select-text);outline:2px dotted var(--retro-select-text);outline-offset:-3px}
.retro-dd .dropdown-divider{height:2px;margin:3px 2px;border:0;opacity:1;box-shadow:inset 0 1px var(--retro-shadow),inset 0 -1px var(--retro-hilite)}
/* Menu bar and drop-down menus (disclosure buttons and lists of links or buttons) */
.retro-menubar{display:flex;flex-wrap:wrap;margin:0;padding:1px 0;list-style:none}
.retro-menubar>li{position:relative}
.retro-menubar__btn{display:block;margin:0;padding:4px 9px;border:0;border-radius:0;background:transparent;color:var(--retro-text);font:400 .875rem/1.3 var(--retro-font);cursor:pointer}
.retro-menubar__btn:hover,.retro-menubar__btn[aria-expanded="true"],.retro-menubar__btn:focus-visible{background:var(--retro-select);color:var(--retro-select-text)}
.retro-menubar__btn:focus-visible{outline:2px dotted var(--retro-select-text);outline-offset:-3px}
.retro-menu{position:absolute;top:100%;left:0;z-index:20;min-width:210px;margin:0;padding:3px;list-style:none;background:var(--retro-face);box-shadow:var(--retro-frame),2px 2px 0 rgba(0,0,0,.4)}
.retro-menu[hidden]{display:none}
.retro-menu__item{display:flex;align-items:center;gap:8px;width:100%;margin:0;padding:5px 12px 5px 8px;border:0;border-radius:0;background:transparent;color:var(--retro-text);
font:400 .875rem/1.3 var(--retro-font);text-align:left;text-decoration:none;white-space:nowrap;cursor:pointer}
.retro-menu__item:hover,.retro-menu__item:focus-visible{background:var(--retro-select);color:var(--retro-select-text)}
.retro-menu__item:focus-visible{outline:2px dotted var(--retro-select-text);outline-offset:-3px}
.retro-menu__mark{display:grid;place-items:center;width:14px;flex:none}
.retro-menu__key{margin-left:auto;padding-left:22px}
.retro-menu__sep{height:2px;margin:3px 2px;box-shadow:inset 0 1px var(--retro-shadow),inset 0 -1px var(--retro-hilite)}
/* Taskbar: Start button, window buttons (the active one is latched in) and a sunken tray */
.retro-taskbar{position:relative;display:flex;flex-wrap:wrap;align-items:center;gap:4px;padding:4px;background:var(--retro-face);box-shadow:inset 0 1px var(--retro-light),inset 0 2px var(--retro-hilite)}
.retro-start{min-width:0;padding:4px 10px 4px 6px;font-weight:700}
.retro-start[aria-expanded="true"]{box-shadow:var(--retro-in)}
.retro-taskbar__apps{display:flex;flex:1 1 220px;gap:4px;min-width:0;margin:0;padding:0;list-style:none}
.retro-taskbar__apps>li{display:flex;flex:0 1 180px;min-width:0}
.retro-taskbtn{justify-content:flex-start;width:100%;min-width:0}
.retro-taskbtn span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.retro-taskbtn[aria-pressed="true"]{box-shadow:var(--retro-in);background:var(--retro-dither);font-weight:700}
.retro-tray{display:flex;align-items:center;gap:8px;min-height:32px;margin-left:auto;padding:3px 10px;box-shadow:var(--retro-thin-in);font:400 .8125rem/1 var(--retro-font);white-space:nowrap}
/* Start menu: a Bootstrap dropup with a vertical banner */
.retro-start.dropdown-toggle::after,.retro-menubar__btn.dropdown-toggle::after{display:none}
.dropdown-menu.retro-startmenu.show{display:flex}
.retro-startmenu.dropdown-menu{padding:3px;min-width:240px}
.retro-startmenu__banner{display:flex;align-items:flex-end;padding:8px 5px;background:linear-gradient(0deg,var(--retro-title),var(--retro-title-2));color:var(--retro-title-text);
font:700 1.05rem/1 var(--retro-font);letter-spacing:.06em;writing-mode:vertical-rl;rotate:180deg}
.retro-startmenu__list{flex:1;margin:0;padding:0;list-style:none}
.retro-startmenu__list .dropdown-item{gap:10px;padding:6px 14px 6px 8px}
/* Media player: an LCD screen, a seek trackbar, transport buttons and a playlist */
.retro-screen{display:grid;gap:6px;padding:10px 12px;background:var(--retro-lcd);color:var(--retro-lcd-text);box-shadow:var(--retro-sunken);font:400 1.2rem/1.1 var(--retro-mono)}
.retro-screen__row{display:flex;align-items:flex-end;justify-content:space-between;gap:12px}
.retro-screen__time{font-size:2.2rem;line-height:1;font-variant-numeric:tabular-nums}
.retro-eq{display:flex;align-items:flex-end;gap:3px;height:34px}
.retro-eq i{display:block;width:6px;height:var(--h);background:repeating-linear-gradient(0deg,var(--retro-lcd-text) 0 3px,transparent 3px 5px)}
.retro-transport{display:flex;flex-wrap:wrap;align-items:center;gap:4px;margin-top:10px}
.retro-transport .retro-btn,.retro-transport .btn-retro{min-width:40px;padding-inline:8px}
.retro-volume{display:flex;flex:1 1 140px;align-items:center;gap:6px;margin-left:auto;max-width:190px}
.retro-playlist{margin:10px 0 0;padding:3px;list-style:none;background:var(--retro-field);color:var(--retro-field-text);box-shadow:var(--retro-sunken);counter-reset:t}
.retro-playlist li{display:flex;gap:8px;padding:3px 6px;counter-increment:t}
.retro-playlist li::before{content:counter(t,decimal-leading-zero) "."}
.retro-playlist li span:last-child{margin-left:auto;font-variant-numeric:tabular-nums}
.retro-playlist [aria-current]{background:var(--retro-select);color:var(--retro-select-text)}
/* Message boxes: an icon, the message and centred buttons */
.retro-msg{display:flex;align-items:flex-start;gap:14px;padding:16px 14px 8px}
.retro-msg__text{display:grid;gap:6px;padding-top:4px}
.retro-actions--center{justify-content:center;padding:10px 12px 12px}
/* Native <dialog>: focus moves in, Tab stays inside and Escape closes it */
.retro-dialog{width:min(430px,calc(100vw - 32px));max-width:none;margin:auto;padding:0;border:0;background:transparent;color:var(--retro-text);overflow:visible}
.retro-dialog::backdrop{background:rgba(0,0,0,.45)}
.retro-dialog[open]{animation:retro-open .2s steps(4)}
@keyframes retro-open{from{clip-path:inset(0 100% 100% 0)}to{clip-path:inset(0)}}
/* File explorer: a folder tree of <details> and a file table, each in a sunken pane */
.retro-explorer{display:grid;grid-template-columns:minmax(150px,210px) minmax(0,1fr);gap:3px}
@media (max-width:640px){.retro-explorer{grid-template-columns:minmax(0,1fr)}}
.retro-pane{min-width:0;overflow:auto;padding:4px;background:var(--retro-field);color:var(--retro-field-text);box-shadow:var(--retro-sunken);font:400 .875rem/1.3 var(--retro-font)}
.retro-tree,.retro-tree ul{margin:0;padding:0;list-style:none}
.retro-tree ul{margin-left:8px;padding-left:10px;border-left:1px dotted var(--retro-muted)}
.retro-tree summary{display:flex;align-items:center;gap:5px;padding:2px 3px;cursor:pointer;list-style:none}
.retro-tree summary::-webkit-details-marker{display:none}
.retro-tree summary::before{content:"+";display:grid;place-items:center;flex:none;width:11px;height:11px;border:1px solid var(--retro-muted);background:var(--retro-field);color:var(--retro-field-text);font:700 11px/1 var(--retro-font)}
.retro-tree details[open]>summary::before{content:"\2212"}
.retro-tree a{display:flex;align-items:center;gap:5px;padding:2px 3px 2px 19px;color:inherit;text-decoration:none}
.retro-tree summary:focus-visible,.retro-tree a:focus-visible{outline:2px dotted var(--retro-focus);outline-offset:-1px}
.retro-tree [aria-current]{background:var(--retro-select);color:var(--retro-select-text)}
.retro-files{width:100%;border-collapse:collapse;color:var(--retro-field-text);font:400 .875rem/1.3 var(--retro-font)}
.retro-files th{padding:4px 8px;background:var(--retro-face);color:var(--retro-text);font-weight:400;text-align:left;box-shadow:var(--retro-out)}
.retro-files td{padding:3px 8px;white-space:nowrap}
.retro-files .num{text-align:right}
.retro-files a{display:inline-flex;align-items:center;gap:6px;color:inherit;text-decoration:none}
.retro-files tbody tr:hover td,.retro-files tbody tr:focus-within td{background:var(--retro-select);color:var(--retro-select-text)}
.retro-files a:focus-visible{outline:2px dotted currentColor;outline-offset:1px}
/* Desktop: icons, draggable windows and a taskbar with a classic / synthwave switch */
.retro-desktop{position:relative;display:flex;flex-direction:column;min-height:700px;overflow:hidden;background:var(--retro-wallpaper);box-shadow:var(--retro-window)}
.retro-desktop__area{position:relative;flex:1;min-height:640px;isolation:isolate}
.retro-desktop__icons{position:absolute;top:14px;left:10px;z-index:1;display:grid;gap:12px;margin:0;padding:0;list-style:none}
.retro-desk-icon{display:flex;flex-direction:column;align-items:center;gap:5px;width:86px;margin:0;padding:4px 2px;border:0;background:transparent;color:var(--retro-desk-text);font:400 .8125rem/1.2 var(--retro-font);text-align:center;cursor:pointer}
.retro-desk-icon span{padding:1px 4px;background:var(--retro-desk)}
.retro-desk-icon:hover span,.retro-desk-icon:focus-visible span{background:var(--retro-select);color:var(--retro-select-text)}
.retro-desk-icon:focus-visible{outline:2px dotted var(--retro-desk-text);outline-offset:1px}
.retro-desk-win{position:absolute;left:var(--x);top:var(--y);z-index:2;width:var(--w);max-width:calc(100% - 16px)}
.retro-desk-win[hidden]{display:none}
.retro-titlebar[data-idle]{background:var(--retro-idle-bg);color:var(--retro-idle-text)}
.retro-titlebar[data-drag]{cursor:move;touch-action:none;user-select:none}
.retro-mover{display:grid;place-items:center;width:22px;height:22px;margin:0;padding:0;border:0;background:transparent;color:inherit;cursor:move}
.retro-mover:focus-visible{outline:2px dotted currentColor;outline-offset:-1px}
.retro-desktop .retro-taskbar{position:relative;z-index:5}
.retro-taskbar__apps>li[hidden]{display:none}
.retro-desktop__floor,.retro-desktop__sun{display:none}
[data-retro]:is([data-retro="synthwave"],:has(.retro-theme-input:checked)) :is(.retro-desktop__floor,.retro-desktop__sun){display:block}
.retro-desktop__floor{position:absolute;z-index:-1;left:-60%;right:-60%;top:58%;height:520px;transform:perspective(320px) rotateX(62deg);transform-origin:top;
background:repeating-linear-gradient(90deg,var(--retro-neon-pink) 0 2px,transparent 2px 64px),repeating-linear-gradient(0deg,var(--retro-neon-pink) 0 2px,transparent 2px 44px);opacity:.45;
-webkit-mask:linear-gradient(#000,transparent 85%);mask:linear-gradient(#000,transparent 85%)}
.retro-desktop__sun{position:absolute;z-index:-1;right:8%;top:calc(58% - 190px);width:240px;aspect-ratio:1;border-radius:50%;background:linear-gradient(var(--retro-sun-1),var(--retro-sun-2) 75%);box-shadow:0 0 60px rgba(255,63,164,.45);
-webkit-mask:linear-gradient(#000 50%,transparent 50% 54%,#000 54% 61%,transparent 61% 66%,#000 66% 72%,transparent 72% 78%,#000 78% 84%,transparent 84% 91%,#000 91%);
mask:linear-gradient(#000 50%,transparent 50% 54%,#000 54% 61%,transparent 61% 66%,#000 66% 72%,transparent 72% 78%,#000 78% 84%,transparent 84% 91%,#000 91%)}
@media (max-width:760px){.retro-desktop{min-height:0}.retro-desktop__area{display:grid;gap:16px;min-height:0;padding:12px}.retro-desktop__icons{position:static;display:flex;flex-wrap:wrap}
.retro-desk-win{position:static;width:auto;max-width:none}.retro-titlebar[data-drag]{cursor:default}}
.btn-retro.retro-btn--icon{--bs-btn-padding-x:8px;min-width:40px}
.retro-seek{margin-top:10px}
.retro-mailpane{max-height:210px}
textarea.form-control.retro-notes{min-height:150px;resize:none}
.retro-startmenu.dropdown-menu[data-bs-popper]{margin-bottom:6px}
.retro-tray .form-check.retro-fc{min-height:0}
@media (prefers-reduced-motion:reduce){[class*="retro-"],[class*="retro-"]::before,[class*="retro-"]::after{transition:none!important;animation:none!important}}
JavaScript
// Player: Play / Pause swaps the button's name and glyph; while playing the seek bar moves once a second.
// The seek bar's time read-out and aria-valuetext follow it as you drag or use the arrow keys.
document.querySelectorAll('[data-retro-player]').forEach(function (p) {
var seek = p.querySelector('[data-seek]'), out = p.querySelector('[data-time]'), play = p.querySelector('[data-play]');
var state = p.querySelector('[data-state]'), timer = null;
function fmt(s) { return String(Math.floor(s / 60)).padStart(2, '0') + ':' + String(s % 60).padStart(2, '0'); }
function words(s) { return Math.floor(s / 60) + ' min ' + (s % 60) + ' s'; }
function sync() {
var s = +seek.value;
out.textContent = fmt(s);
seek.setAttribute('aria-valuetext', words(s) + ' of ' + words(+seek.max));
}
function setPlaying(on) {
play.setAttribute('aria-label', on ? 'Pause' : 'Play');
play.querySelector('[data-icon="play"]').hidden = on;
play.querySelector('[data-icon="pause"]').hidden = !on;
if (state) state.textContent = on ? 'Playing' : 'Paused';
clearInterval(timer);
if (on) timer = setInterval(function () { seek.value = Math.min(+seek.value + 1, +seek.max); sync(); if (+seek.value >= +seek.max) setPlaying(false); }, 1000);
}
seek.addEventListener('input', sync);
play.addEventListener('click', function () { setPlaying(play.getAttribute('aria-label') === 'Play'); });
var stop = p.querySelector('[data-stop]');
if (stop) stop.addEventListener('click', function () { setPlaying(false); seek.value = 0; sync(); });
sync();
});
// Desktop: drag a window by its title bar, or focus its icon button and use the arrow keys (Shift moves further).
// Clicking or focusing a window brings it to the front; the taskbar shows which one is active.
(function () {
var desk = document.querySelector('[data-retro-desktop]'); if (!desk) return;
var area = desk.querySelector('[data-desk-area]');
var wins = Array.prototype.slice.call(desk.querySelectorAll('[data-win]'));
var z = 10;
function movable() { return window.matchMedia('(min-width: 761px)').matches; }
function task(win) { return desk.querySelector('[data-task="' + win.id + '"]'); }
function activate(win) {
wins.forEach(function (w) {
var on = w === win;
w.querySelector('[data-drag]').toggleAttribute('data-idle', !on);
var t = task(w); if (t) t.setAttribute('aria-pressed', String(on && !w.hidden));
});
win.style.zIndex = ++z;
}
function show(win) {
win.hidden = false;
var t = task(win); if (t) t.parentElement.hidden = false;
activate(win); win.querySelector('[data-move]').focus();
}
function place(win, x, y) {
x = Math.max(0, Math.min(x, area.clientWidth - win.offsetWidth));
y = Math.max(0, Math.min(y, area.clientHeight - win.offsetHeight));
win.style.left = x + 'px'; win.style.top = y + 'px';
}
wins.forEach(function (win) {
var bar = win.querySelector('[data-drag]'), mover = win.querySelector('[data-move]');
win.addEventListener('pointerdown', function () { activate(win); });
win.addEventListener('focusin', function () { activate(win); });
bar.addEventListener('pointerdown', function (e) {
if (e.button !== 0 || !movable() || e.target.closest('button:not([data-move])')) return;
var dx = e.clientX - win.offsetLeft, dy = e.clientY - win.offsetTop;
bar.setPointerCapture(e.pointerId);
function move(ev) { place(win, ev.clientX - dx, ev.clientY - dy); }
function up() { bar.removeEventListener('pointermove', move); bar.removeEventListener('pointerup', up); }
bar.addEventListener('pointermove', move); bar.addEventListener('pointerup', up);
});
mover.addEventListener('keydown', function (e) {
var d = { ArrowLeft: [-1, 0], ArrowRight: [1, 0], ArrowUp: [0, -1], ArrowDown: [0, 1] }[e.key];
if (!d || !movable()) return;
e.preventDefault();
var step = e.shiftKey ? 64 : 16;
place(win, win.offsetLeft + d[0] * step, win.offsetTop + d[1] * step);
});
win.querySelector('[data-min]').addEventListener('click', function () {
win.hidden = true;
var t = task(win); t.setAttribute('aria-pressed', 'false'); t.focus();
});
win.querySelector('[data-close]').addEventListener('click', function () {
win.hidden = true;
var t = task(win); if (t) t.parentElement.hidden = true;
var icon = desk.querySelector('[data-open="' + win.id + '"]'); if (icon) icon.focus();
});
});
desk.querySelectorAll('[data-task]').forEach(function (t) {
t.addEventListener('click', function () {
var win = document.getElementById(t.getAttribute('data-task'));
if (win.hidden) { show(win); return; }
if (t.getAttribute('aria-pressed') === 'true') { win.hidden = true; t.setAttribute('aria-pressed', 'false'); return; }
activate(win); win.querySelector('[data-move]').focus();
});
});
desk.querySelectorAll('[data-open]').forEach(function (b) {
b.addEventListener('click', function () { show(document.getElementById(b.getAttribute('data-open'))); });
});
var clock = desk.querySelector('[data-desk-clock]');
function tick() {
var d = new Date();
clock.textContent = d.toLocaleTimeString('en-GB', { hour: '2-digit', minute: '2-digit' });
clock.setAttribute('datetime', clock.textContent);
}
if (clock) { tick(); setInterval(tick, 15000); }
})();
/* ── Retro UI kit tokens (uiCookies) — identical in every set ─────────────
A classic desktop OS look: grey bevelled faces, navy title bars, sunken white fields on a dithered teal desktop.
Bevels are four 1px inset shadows built from --retro-hilite, --retro-light, --retro-shadow and --retro-dark,
so one change to a token re-colours every button, field and window in the kit. */
:root{
--retro-desk:#006e6e; /* desktop behind the windows */
--retro-desk-text:#ffffff; /* captions and icon labels on the desktop, 6.1:1 */
--retro-desk-dither:rgba(0,0,0,.22);
--retro-face:#c0c0c0; /* window, button and bar faces */
--retro-hilite:#ffffff; /* bevel: outer light edge */
--retro-light:#dfdfdf; /* bevel: inner light edge */
--retro-shadow:#808080; /* bevel: inner dark edge */
--retro-dark:#0a0a0a; /* bevel: outer dark edge */
--retro-text:#000000; /* text on faces, 11.5:1 */
--retro-muted:#3d3d3d; /* secondary text on faces, 6:1 */
--retro-field:#ffffff; /* inputs, lists and document areas */
--retro-field-text:#000000;
--retro-title:#000080; /* active title bar gradient, white text 6.3:1 or more */
--retro-title-2:#1060b0;
--retro-title-text:#ffffff;
--retro-idle:#5a5a5a; /* inactive title bar gradient, white text 5.3:1 or more */
--retro-idle-2:#6b6b6b;
--retro-idle-text:#ffffff;
--retro-select:#000080; /* highlighted menu items, rows and dates */
--retro-select-text:#ffffff;
--retro-link:#0000cc; /* 6.2:1 on faces */
--retro-danger:#8a0000; /* error text, 5.5:1 on faces */
--retro-tip:#ffffe1; /* tooltips and balloons */
--retro-tip-text:#000000;
--retro-tip-line:#000000;
--retro-lcd:#0b1a0b; /* LCD read-outs */
--retro-lcd-text:#4dff4d;
--retro-accent:#000080; /* progress chunks */
--retro-disabled:#808080; /* disabled text, embossed */
--retro-emboss:#ffffff;
--retro-dither-a:#ffffff; /* checkerboard behind a latched toggle */
--retro-dither-b:#c0c0c0;
--retro-focus:#000000; /* dotted focus rectangle */
--retro-glow:0 0 #0000; /* the synthwave theme adds a neon glow to windows */
--retro-neon-pink:#ff3fa4;--retro-neon-cyan:#00e5ff;--retro-sun-1:#ffd23f;--retro-sun-2:#ff3fa4;
--retro-font:Tahoma,"Microsoft Sans Serif","MS Sans Serif",Geneva,Verdana,"Segoe UI",sans-serif;
--retro-mono:"VT323","Fixedsys","Lucida Console",Consolas,Menlo,"Courier New",ui-monospace,monospace;
}
/* Synthwave 80s night theme: data-retro="synthwave" on any wrapper, or a checked .retro-theme-input inside a
[data-retro] element. :is() is a forgiving list, so browsers without :has() still apply the attribute. */
[data-retro]:is([data-retro="synthwave"],:has(.retro-theme-input:checked)){
--retro-desk:#14062b;--retro-desk-text:#fff1fb;--retro-desk-dither:rgba(255,63,164,.16);
--retro-face:#261047;--retro-hilite:#ff6ec7;--retro-light:#a05cff;--retro-shadow:#0d0420;--retro-dark:#000000;
--retro-text:#fff1fb;--retro-muted:#dcc6ff;--retro-field:#0e0322;--retro-field-text:#fff1fb;
--retro-title:#ff8a3d;--retro-title-2:#ff3fa4;--retro-title-text:#1b0030;
--retro-idle:#4a2d6e;--retro-idle-2:#5c3a85;--retro-idle-text:#f3e8ff;
--retro-select:#00e5ff;--retro-select-text:#14062b;--retro-link:#7cf3ff;--retro-danger:#ff8fa3;
--retro-tip:#2b1352;--retro-tip-text:#fff1fb;--retro-tip-line:#ff6ec7;
--retro-lcd:#07010f;--retro-lcd-text:#ff5fd2;--retro-accent:#ff3fa4;
--retro-disabled:#8a72b0;--retro-emboss:transparent;--retro-dither-a:#3d1a6e;--retro-dither-b:#261047;
--retro-focus:#5ff4ff;--retro-glow:0 0 0 1px rgba(255,63,164,.45),0 0 22px rgba(255,63,164,.35);color-scheme:dark}
/* More contrast requested: secondary text turns full strength and the glow goes */
@media (prefers-contrast:more){:root,[data-retro],[data-retro]:is([data-retro="synthwave"],:has(.retro-theme-input:checked)){--retro-muted:var(--retro-text);--retro-glow:0 0 #0000}}
:root,[data-retro]{
--retro-out:inset -1px -1px var(--retro-dark),inset 1px 1px var(--retro-hilite),inset -2px -2px var(--retro-shadow),inset 2px 2px var(--retro-light);
--retro-in:inset -1px -1px var(--retro-hilite),inset 1px 1px var(--retro-dark),inset -2px -2px var(--retro-light),inset 2px 2px var(--retro-shadow);
--retro-out-default:inset 0 0 0 1px var(--retro-dark),inset -2px -2px var(--retro-dark),inset 2px 2px var(--retro-hilite),inset -3px -3px var(--retro-shadow),inset 3px 3px var(--retro-light);
--retro-in-default:inset 0 0 0 1px var(--retro-dark),inset 2px 2px var(--retro-shadow),inset -2px -2px var(--retro-shadow);
--retro-sunken:inset -1px -1px var(--retro-hilite),inset 1px 1px var(--retro-shadow),inset -2px -2px var(--retro-light),inset 2px 2px var(--retro-dark);
--retro-frame:inset -1px -1px var(--retro-dark),inset 1px 1px var(--retro-light),inset -2px -2px var(--retro-shadow),inset 2px 2px var(--retro-hilite);
--retro-window:var(--retro-frame),var(--retro-glow);
--retro-thin-in:inset -1px -1px var(--retro-hilite),inset 1px 1px var(--retro-shadow);
--retro-thin-out:inset -1px -1px var(--retro-shadow),inset 1px 1px var(--retro-hilite);
--retro-title-bg:linear-gradient(90deg,var(--retro-title),var(--retro-title-2));
--retro-idle-bg:linear-gradient(90deg,var(--retro-idle),var(--retro-idle-2));
--retro-dither:repeating-conic-gradient(var(--retro-dither-a) 0 25%,var(--retro-dither-b) 0 50%) 0 0/2px 2px;
--retro-wallpaper:radial-gradient(var(--retro-desk-dither) 1px,transparent 1.5px) 0 0/4px 4px,var(--retro-desk);
--retro-check-mask:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%207%207'%20shape-rendering='crispEdges'%3E%3Crect%20x='6'%20y='0'%20width='1'%20height='1'%20fill='%23000'/%3E%3Crect%20x='5'%20y='1'%20width='2'%20height='1'%20fill='%23000'/%3E%3Crect%20x='0'%20y='2'%20width='1'%20height='1'%20fill='%23000'/%3E%3Crect%20x='4'%20y='2'%20width='3'%20height='1'%20fill='%23000'/%3E%3Crect%20x='0'%20y='3'%20width='2'%20height='1'%20fill='%23000'/%3E%3Crect%20x='3'%20y='3'%20width='3'%20height='1'%20fill='%23000'/%3E%3Crect%20x='0'%20y='4'%20width='5'%20height='1'%20fill='%23000'/%3E%3Crect%20x='1'%20y='5'%20width='3'%20height='1'%20fill='%23000'/%3E%3Crect%20x='2'%20y='6'%20width='1'%20height='1'%20fill='%23000'/%3E%3C/svg%3E");
--retro-arrow-mask:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%207%204'%20shape-rendering='crispEdges'%3E%3Crect%20x='0'%20y='0'%20width='7'%20height='1'%20fill='%23000'/%3E%3Crect%20x='1'%20y='1'%20width='5'%20height='1'%20fill='%23000'/%3E%3Crect%20x='2'%20y='2'%20width='3'%20height='1'%20fill='%23000'/%3E%3Crect%20x='3'%20y='3'%20width='1'%20height='1'%20fill='%23000'/%3E%3C/svg%3E");
}
[data-retro]{color:var(--retro-text);font-family:var(--retro-font)}
/* The tokens above, exposed as Tailwind utilities: bg-retro-face, text-retro-text, shadow-retro-out,
shadow-retro-in, shadow-retro-sunken, shadow-retro-window, outline-retro-focus, font-retro, font-retro-mono… */
@theme inline {
--color-retro-desk: var(--retro-desk); --color-retro-desk-text: var(--retro-desk-text); --color-retro-face: var(--retro-face);
--color-retro-hilite: var(--retro-hilite); --color-retro-light: var(--retro-light); --color-retro-shadow: var(--retro-shadow); --color-retro-dark: var(--retro-dark);
--color-retro-text: var(--retro-text); --color-retro-muted: var(--retro-muted); --color-retro-field: var(--retro-field); --color-retro-field-text: var(--retro-field-text);
--color-retro-title-text: var(--retro-title-text); --color-retro-idle-text: var(--retro-idle-text);
--color-retro-select: var(--retro-select); --color-retro-select-text: var(--retro-select-text); --color-retro-link: var(--retro-link); --color-retro-danger: var(--retro-danger);
--color-retro-tip: var(--retro-tip); --color-retro-tip-text: var(--retro-tip-text); --color-retro-tip-line: var(--retro-tip-line);
--color-retro-lcd: var(--retro-lcd); --color-retro-lcd-text: var(--retro-lcd-text); --color-retro-accent: var(--retro-accent);
--color-retro-disabled: var(--retro-disabled); --color-retro-focus: var(--retro-focus);
--color-retro-neon-pink: var(--retro-neon-pink); --color-retro-neon-cyan: var(--retro-neon-cyan);
--shadow-retro-out: var(--retro-out); --shadow-retro-in: var(--retro-in); --shadow-retro-default: var(--retro-out-default); --shadow-retro-default-in: var(--retro-in-default);
--shadow-retro-sunken: var(--retro-sunken); --shadow-retro-frame: var(--retro-frame); --shadow-retro-window: var(--retro-window);
--shadow-retro-thin-in: var(--retro-thin-in); --shadow-retro-thin-out: var(--retro-thin-out);
--font-retro: var(--retro-font); --font-retro-mono: var(--retro-mono);
}
/* Synthwave scene: night sky, a striped sun and a neon grid floor (decoration only) */
@utility retro-synth-sky {
background: radial-gradient(1.5px 1.5px at 12% 14%,#fff 50%,transparent 51%),radial-gradient(1px 1px at 33% 7%,#fff 50%,transparent 51%),radial-gradient(1.5px 1.5px at 58% 18%,#ffd6f2 50%,transparent 51%),
radial-gradient(1px 1px at 81% 9%,#fff 50%,transparent 51%),radial-gradient(1px 1px at 92% 26%,#c9f9ff 50%,transparent 51%),radial-gradient(1.5px 1.5px at 22% 31%,#fff 50%,transparent 51%),
linear-gradient(180deg,#07001a 0,#1a0638 420px,#3d0b5c 640px,#14062b 640px);
}
@utility retro-synth-floor {
position: absolute; z-index: -1; top: 640px; left: -60%; right: -60%; height: 900px; transform: perspective(380px) rotateX(62deg); transform-origin: top;
background: repeating-linear-gradient(90deg,var(--retro-neon-pink) 0 2px,transparent 2px 64px),repeating-linear-gradient(0deg,var(--retro-neon-pink) 0 2px,transparent 2px 44px); opacity: .55;
-webkit-mask: linear-gradient(#000,transparent 85%); mask: linear-gradient(#000,transparent 85%);
}
@utility retro-synth-sun {
background: linear-gradient(var(--retro-sun-1),var(--retro-sun-2) 75%); box-shadow: 0 0 60px rgba(255,63,164,.45);
-webkit-mask: linear-gradient(#000 50%,transparent 50% 54%,#000 54% 61%,transparent 61% 66%,#000 66% 72%,transparent 72% 78%,#000 78% 84%,transparent 84% 91%,#000 91%);
mask: linear-gradient(#000 50%,transparent 50% 54%,#000 54% 61%,transparent 61% 66%,#000 66% 72%,transparent 72% 78%,#000 78% 84%,transparent 84% 91%,#000 91%);
}
JavaScript
// Menus: a button opens its list; Escape, a click outside or opening another menu closes it.
// Arrow Down on a menu button opens it and focuses the first item; Arrow Up and Down move through the items.
(function () {
var toggles = Array.prototype.slice.call(document.querySelectorAll('[data-retro-menu]'));
function menuOf(b) { return document.getElementById(b.getAttribute('aria-controls')); }
function set(b, open) { b.setAttribute('aria-expanded', String(open)); menuOf(b).hidden = !open; }
function only(b, open) { toggles.forEach(function (o) { set(o, o === b ? open : false); }); }
toggles.forEach(function (b) {
var menu = menuOf(b);
b.addEventListener('click', function () { only(b, b.getAttribute('aria-expanded') !== 'true'); });
b.addEventListener('keydown', function (e) {
if (e.key !== 'ArrowDown') return;
e.preventDefault(); only(b, true);
var first = menu.querySelector('a, button'); if (first) first.focus();
});
menu.addEventListener('keydown', function (e) {
if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp') return;
e.preventDefault();
var items = Array.prototype.slice.call(menu.querySelectorAll('a, button'));
var i = items.indexOf(document.activeElement) + (e.key === 'ArrowDown' ? 1 : -1);
items[(i + items.length) % items.length].focus();
});
menu.addEventListener('click', function (e) { if (e.target.closest('a, button')) { set(b, false); b.focus(); } });
});
document.addEventListener('click', function (e) {
toggles.forEach(function (b) { if (!b.contains(e.target) && !menuOf(b).contains(e.target)) set(b, false); });
});
document.addEventListener('keydown', function (e) {
if (e.key !== 'Escape') return;
toggles.forEach(function (b) {
if (b.getAttribute('aria-expanded') !== 'true') return;
var inside = menuOf(b).contains(document.activeElement);
set(b, false); if (inside) b.focus();
});
});
})();
// Player: Play / Pause swaps the button's name and glyph; while playing the seek bar moves once a second.
// The seek bar's time read-out and aria-valuetext follow it as you drag or use the arrow keys.
document.querySelectorAll('[data-retro-player]').forEach(function (p) {
var seek = p.querySelector('[data-seek]'), out = p.querySelector('[data-time]'), play = p.querySelector('[data-play]');
var state = p.querySelector('[data-state]'), timer = null;
function fmt(s) { return String(Math.floor(s / 60)).padStart(2, '0') + ':' + String(s % 60).padStart(2, '0'); }
function words(s) { return Math.floor(s / 60) + ' min ' + (s % 60) + ' s'; }
function sync() {
var s = +seek.value;
out.textContent = fmt(s);
seek.setAttribute('aria-valuetext', words(s) + ' of ' + words(+seek.max));
}
function setPlaying(on) {
play.setAttribute('aria-label', on ? 'Pause' : 'Play');
play.querySelector('[data-icon="play"]').hidden = on;
play.querySelector('[data-icon="pause"]').hidden = !on;
if (state) state.textContent = on ? 'Playing' : 'Paused';
clearInterval(timer);
if (on) timer = setInterval(function () { seek.value = Math.min(+seek.value + 1, +seek.max); sync(); if (+seek.value >= +seek.max) setPlaying(false); }, 1000);
}
seek.addEventListener('input', sync);
play.addEventListener('click', function () { setPlaying(play.getAttribute('aria-label') === 'Play'); });
var stop = p.querySelector('[data-stop]');
if (stop) stop.addEventListener('click', function () { setPlaying(false); seek.value = 0; sync(); });
sync();
});
// Desktop: drag a window by its title bar, or focus its icon button and use the arrow keys (Shift moves further).
// Clicking or focusing a window brings it to the front; the taskbar shows which one is active.
(function () {
var desk = document.querySelector('[data-retro-desktop]'); if (!desk) return;
var area = desk.querySelector('[data-desk-area]');
var wins = Array.prototype.slice.call(desk.querySelectorAll('[data-win]'));
var z = 10;
function movable() { return window.matchMedia('(min-width: 761px)').matches; }
function task(win) { return desk.querySelector('[data-task="' + win.id + '"]'); }
function activate(win) {
wins.forEach(function (w) {
var on = w === win;
w.querySelector('[data-drag]').toggleAttribute('data-idle', !on);
var t = task(w); if (t) t.setAttribute('aria-pressed', String(on && !w.hidden));
});
win.style.zIndex = ++z;
}
function show(win) {
win.hidden = false;
var t = task(win); if (t) t.parentElement.hidden = false;
activate(win); win.querySelector('[data-move]').focus();
}
function place(win, x, y) {
x = Math.max(0, Math.min(x, area.clientWidth - win.offsetWidth));
y = Math.max(0, Math.min(y, area.clientHeight - win.offsetHeight));
win.style.left = x + 'px'; win.style.top = y + 'px';
}
wins.forEach(function (win) {
var bar = win.querySelector('[data-drag]'), mover = win.querySelector('[data-move]');
win.addEventListener('pointerdown', function () { activate(win); });
win.addEventListener('focusin', function () { activate(win); });
bar.addEventListener('pointerdown', function (e) {
if (e.button !== 0 || !movable() || e.target.closest('button:not([data-move])')) return;
var dx = e.clientX - win.offsetLeft, dy = e.clientY - win.offsetTop;
bar.setPointerCapture(e.pointerId);
function move(ev) { place(win, ev.clientX - dx, ev.clientY - dy); }
function up() { bar.removeEventListener('pointermove', move); bar.removeEventListener('pointerup', up); }
bar.addEventListener('pointermove', move); bar.addEventListener('pointerup', up);
});
mover.addEventListener('keydown', function (e) {
var d = { ArrowLeft: [-1, 0], ArrowRight: [1, 0], ArrowUp: [0, -1], ArrowDown: [0, 1] }[e.key];
if (!d || !movable()) return;
e.preventDefault();
var step = e.shiftKey ? 64 : 16;
place(win, win.offsetLeft + d[0] * step, win.offsetTop + d[1] * step);
});
win.querySelector('[data-min]').addEventListener('click', function () {
win.hidden = true;
var t = task(win); t.setAttribute('aria-pressed', 'false'); t.focus();
});
win.querySelector('[data-close]').addEventListener('click', function () {
win.hidden = true;
var t = task(win); if (t) t.parentElement.hidden = true;
var icon = desk.querySelector('[data-open="' + win.id + '"]'); if (icon) icon.focus();
});
});
desk.querySelectorAll('[data-task]').forEach(function (t) {
t.addEventListener('click', function () {
var win = document.getElementById(t.getAttribute('data-task'));
if (win.hidden) { show(win); return; }
if (t.getAttribute('aria-pressed') === 'true') { win.hidden = true; t.setAttribute('aria-pressed', 'false'); return; }
activate(win); win.querySelector('[data-move]').focus();
});
});
desk.querySelectorAll('[data-open]').forEach(function (b) {
b.addEventListener('click', function () { show(document.getElementById(b.getAttribute('data-open'))); });
});
var clock = desk.querySelector('[data-desk-clock]');
function tick() {
var d = new Date();
clock.textContent = d.toLocaleTimeString('en-GB', { hour: '2-digit', minute: '2-digit' });
clock.setAttribute('datetime', clock.textContent);
}
if (clock) { tick(); setInterval(tick, 15000); }
})();
About this set
A complete retro desktop built from the kit. Desktop icons for Notes, Inbox, Nightdrive FM and the Recycle Bin open their windows. Each window can be dragged by its title bar with a mouse, pen or finger, and has a keyboard alternative: focus the small icon button at the left of the title bar and press the arrow keys to move it 16 pixels, or 64 with Shift, kept inside the desktop. Clicking or focusing a window brings it to the front, switches its title bar to the active gradient and the others to grey, and latches its taskbar button. Minimise hides a window to the taskbar, the taskbar button restores it, and Close removes it until its desktop icon opens it again. The windows hold an inbox table with unread mail marked in words, a notepad text area and a small music player. The taskbar has a Start menu, window buttons and a tray with the time and a Synthwave checkbox that re-themes the whole desktop through :has() with no JavaScript, adding the neon grid and sun. Under 761 pixels the windows stack in a column and dragging switches off.
What’s included
Windows that drag by the title bar and move with the arrow keys
Active and inactive title bars that follow focus
Minimise to the taskbar, restore and close with focus kept in place
Synthwave theme switch through :has() with no script
Stacks into one column on small screens
Accessibility
Every window is a section labelled by its title, and the move button is named, for example Move the Notes window, with a hidden hint about the arrow keys. Minimise, close and taskbar buttons have names, taskbar buttons report aria-pressed, and focus moves to the taskbar button or the desktop icon when a window is hidden. Focus is a 2px dotted rectangle. Dragging is never the only way to move a window.
Customise it
Set each window's start position and width with --x, --y and --w in its style attribute, and recolour the desktop with --retro-desk and --retro-desk-dither. Bootstrap uses its dropdown plugin for the Start menu; Tailwind uses data-idle: variants for inactive title bars.