/* OBSCURA OS: the front door as the application (home-shell.js).

   One window that fills the screen: the site's bar along the top, a dense
   sidebar down the left, and the main area, which holds Today and the
   tabs. Everything is the site's tokens (theme.css). Today is the ways to
   start and every application as a mark and a name, and nothing explaining
   them (the owner, 7 October 2026).

   Without a script the same markup is a page: the sidebar is a column of
   links beside Today, and on a phone it follows Today down the page. */

/* ------------------------------------------------------------ the window */

.hx-page{margin:0;background:var(--paper);}
@media (min-width:761px){
  .hx-page{height:100vh;height:100dvh;display:flex;flex-direction:column;overflow:hidden;}
}
.hx-page .os-topbar{flex:none;max-width:none;margin:0;border-radius:0;border-left:0;border-right:0;
  box-shadow:none;padding:6px 14px;min-height:48px;}
.hx{flex:1 1 auto;min-height:0;display:grid;grid-template-columns:264px minmax(0,1fr);}

/* ------------------------------------------------------------ the sidebar */

.hx-side{display:flex;flex-direction:column;min-height:0;background:var(--paper-inset);
  border-right:1px solid var(--rule);font-size:var(--text-sm);color:var(--ink-soft);}
.hx-side-top{flex:none;display:flex;align-items:center;gap:6px;padding:10px 10px 8px;}
.hx-side-x{display:none;}
.hx-find{position:relative;flex:1 1 auto;margin:0;}
.hx-find-label{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;}
.hx-find-ico{position:absolute;left:9px;top:50%;width:15px;height:15px;transform:translateY(-50%);color:var(--ink-faint);pointer-events:none;}
.hx-find-input{box-sizing:border-box;width:100%;height:32px;padding:0 30px 0 30px;border:1px solid var(--rule);
  border-radius:var(--radius-sm);background:var(--paper-raised);color:var(--ink);font:inherit;font-size:var(--text-sm);}
.hx-find-input::placeholder{color:var(--ink-faint);}
.hx-find-input:focus-visible{outline:2px solid var(--focus);outline-offset:0;border-color:transparent;}
.hx-find-input::-webkit-search-cancel-button{display:none;}
.hx-find-key{position:absolute;right:7px;top:50%;transform:translateY(-50%);padding:0 5px;border:1px solid var(--rule);
  border-radius:var(--radius-sm);font:500 var(--text-2xs)/16px var(--font-mono);color:var(--ink-faint);background:var(--paper);}
.hx-find-input:focus ~ .hx-find-key{display:none;}
@media (pointer:coarse){ .hx-find-key{display:none;} }

.hx-nav,.hx-results{flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;padding:2px 8px 16px;}
.hx-nav[hidden],.hx-results[hidden]{display:none;}
.hx-side-foot{flex:none;display:flex;flex-direction:column;gap:1px;padding:6px 8px 8px;border-top:1px solid var(--rule);}

.hx-sect{margin-top:14px;}
.hx .hx-sect-head{display:flex;align-items:baseline;justify-content:space-between;gap:8px;margin:0 0 4px;padding:0 8px;
  font:600 var(--text-2xs)/1.3 var(--font-mono);letter-spacing:.08em;text-transform:uppercase;color:var(--ink-faint);}
.hx-sect-head a{color:inherit;text-decoration:none;}
.hx-sect-head a:hover{color:var(--ink);}
.hx-sect-head a:focus-visible{outline:2px solid var(--focus);outline-offset:2px;border-radius:var(--radius-sm);}
.hx-tag{font-weight:500;letter-spacing:.04em;text-transform:none;font-size:var(--text-2xs);}
.hx-list,.hx-tools{list-style:none;margin:0;padding:0;}

.hx-item{position:relative;display:flex;align-items:center;gap:9px;box-sizing:border-box;width:100%;min-height:30px;
  padding:4px 8px;border:0;border-radius:var(--radius-sm);background:none;color:var(--ink-soft);
  font:inherit;font-size:var(--text-sm);line-height:1.25;text-align:left;text-decoration:none;cursor:pointer;
  transition:background-color var(--dur-2) var(--ease-standard),color var(--dur-2) var(--ease-standard);}
.hx-item:hover{background:var(--paper-raised);color:var(--ink);}
.hx-item:focus-visible{outline:2px solid var(--focus);outline-offset:-2px;}
.hx-item[aria-current="page"]{background:var(--paper-raised);color:var(--ink);font-weight:600;box-shadow:inset 2px 0 0 var(--accent);}
.hx-name{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.hx-meta,.hx-n{flex:none;font:500 var(--text-2xs)/1 var(--font-mono);color:var(--ink-faint);font-variant-numeric:tabular-nums;}
.hx-sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;}

/* The mark: each product's own drawing, as a line in its hue and nothing
   behind it, at the size of the line of text it sits on. */
.hx-ico{flex:none;display:grid;place-items:center;width:18px;height:18px;color:var(--ink-faint);}
.hx-ico svg{width:17px;height:17px;stroke-width:var(--icon-stroke);}
.hx-ico .ico-plane{fill-opacity:var(--ico-plane);}
@supports (color: oklch(0.5 0.1 200)){
  .hx-ico{color:oklch(var(--ico-l) var(--ico-c) var(--ico-h, 258));}
  .hx-ico.is-neutral{color:var(--ink-faint);}
}

.hx-lock{flex:none;display:grid;place-items:center;width:14px;height:14px;color:var(--ink-faint);}
.hx-lock svg{width:13px;height:13px;}
.is-paid .hx-lock,:root[data-pro="on"] .hx-lock{display:none;}

.hx-group > summary{list-style:none;}
.hx-group > summary::-webkit-details-marker{display:none;}
.hx-group > summary::after{content:"";flex:none;width:6px;height:6px;margin:0 3px 0 2px;border-right:1.5px solid var(--ink-faint);
  border-bottom:1.5px solid var(--ink-faint);transform:rotate(-45deg);transition:transform var(--dur-2) var(--ease-standard);}
.hx-group[open] > summary::after{transform:rotate(45deg);}
.hx-tools{margin:2px 0 6px 17px;padding-left:9px;border-left:1px solid var(--rule);}
.hx-tool{display:block;padding:4px 8px;border-radius:var(--radius-sm);color:var(--ink-soft);text-decoration:none;
  font-size:var(--text-xs);line-height:1.35;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.hx-tool:hover{background:var(--paper-raised);color:var(--ink);}
.hx-tool:focus-visible{outline:2px solid var(--focus);outline-offset:-2px;}
.hx-tool[aria-current="page"]{color:var(--ink);font-weight:600;background:var(--paper-raised);}
.hx-tool-all{color:var(--accent-strong);}
.hx-file .hx-meta{font-family:var(--font-ui);}

/* The search's answers, in place of the sidebar while there is a query. */
.hx-res-group{margin-top:10px;}
.hx .hx-res-head{margin:0 0 3px;padding:0 8px;font:600 var(--text-2xs)/1.3 var(--font-mono);letter-spacing:.08em;
  text-transform:uppercase;color:var(--ink-faint);}
.hx-res{display:flex;align-items:center;gap:9px;padding:6px 8px;border-radius:var(--radius-sm);color:var(--ink);text-decoration:none;}
.hx-res:hover,.hx-res.is-act{background:var(--paper-raised);}
.hx-res.is-act{box-shadow:inset 2px 0 0 var(--accent);}
.hx-res-text{display:flex;flex-direction:column;gap:1px;min-width:0;flex:1 1 auto;}
.hx-res-sub{font-size:var(--text-2xs);color:var(--ink-faint);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.hx-res-tag{flex:none;font:600 var(--text-2xs)/1 var(--font-mono);letter-spacing:.06em;color:var(--ink-faint);}
.hx-res-none{margin:14px 8px;font-size:var(--text-sm);line-height:1.5;color:var(--ink-soft);}
.hx-res-none a{color:var(--accent-strong);}

/* ------------------------------------------------------------ the main area */

.hx-main{display:flex;flex-direction:column;min-width:0;min-height:0;background:var(--paper);}
.hx-head{flex:none;display:flex;align-items:stretch;gap:6px;min-height:38px;padding:0 10px;border-bottom:1px solid var(--rule);
  background:var(--paper-inset);}
.hx-menu{display:none;}
/* On a desktop, Menu is the sidebar's switch: an icon at the start of the
   tab strip, and with the sidebar hidden the window is all main area. */
@media (min-width:761px){
  :root.hx-js .hx-menu{display:inline-flex;align-items:center;justify-content:center;flex:none;width:38px;margin:0 2px 0 -6px;padding:0;
    border:0;border-radius:var(--radius-sm);background:transparent;color:var(--ink-faint);cursor:pointer;}
  :root.hx-js .hx-menu span{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;}
  :root.hx-js .hx-menu svg{width:18px;height:18px;}
  :root.hx-js .hx-menu:hover{color:var(--ink);background:var(--paper);}
  :root.hx-js .hx-menu:focus-visible{outline:2px solid var(--focus);outline-offset:-2px;}
  :root.hx-js.hx-side-hidden .hx{grid-template-columns:minmax(0,1fr);}
  :root.hx-js.hx-side-hidden .hx-side{display:none;}
}
.hx-tabs{display:flex;align-items:stretch;gap:2px;min-width:0;overflow-x:auto;scrollbar-width:none;}
.hx-tabs::-webkit-scrollbar{display:none;}
.hx-tab{position:relative;display:inline-flex;align-items:center;gap:7px;flex:none;max-width:220px;box-sizing:border-box;
  padding:0 12px;border:0;color:var(--ink-faint);text-decoration:none;font-size:var(--text-xs);font-weight:500;}
a.hx-tab{min-height:38px;}
.hx-tab:hover{color:var(--ink);}
.hx-tab.is-on{color:var(--ink);background:var(--paper);box-shadow:inset 0 2px 0 var(--accent),1px 0 0 var(--rule),-1px 0 0 var(--rule);}
.hx-tab-link{display:inline-flex;align-items:center;gap:7px;min-width:0;min-height:38px;color:inherit;text-decoration:none;}
span.hx-tab{padding-right:4px;}
.hx-tab-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.hx-tab .hx-ico{width:15px;height:15px;}
.hx-tab .hx-ico svg{width:14px;height:14px;}
.hx-tab-x{display:grid;place-items:center;flex:none;width:24px;height:24px;padding:0;border:0;border-radius:var(--radius-sm);
  background:none;color:var(--ink-faint);cursor:pointer;}
.hx-tab-x svg{width:13px;height:13px;}
.hx-tab-x:hover{background:var(--paper-inset);color:var(--ink);}
.hx-tab :focus-visible,a.hx-tab:focus-visible{outline:2px solid var(--focus);outline-offset:-2px;}
.hx-dot{flex:none;width:6px;height:6px;border-radius:50%;background:var(--accent);}

.hx-view{flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior-y:contain;}
/* The window does not move. Its views scroll inside it, and a pull past
   the top of one used to carry on to the page: on an iPhone the whole
   window, bar and all, slid down and bounced back, and a long enough pull
   reloaded the page and closed every tab. */
:root.hx-js{overscroll-behavior:none;}
.hx-view[hidden]{display:none;}
.hx-frames{display:none;position:relative;flex:1 1 auto;min-height:0;}
.hx-frames.is-on{display:block;}
.hx-frame{position:absolute;inset:0;width:100%;height:100%;border:0;background:var(--paper);}
.hx-frame[hidden]{display:none;}

/* ------------------------------------------------------------ Today */

.hx-today{box-sizing:border-box;max-width:780px;padding:28px 36px 0;}
.hx-intro{max-width:68ch;}
.hx-kicker{margin:0 0 10px;font:600 var(--text-2xs)/1.3 var(--font-mono);letter-spacing:.08em;text-transform:uppercase;color:var(--ink-faint);}
.hx-title{margin:0;font-size:var(--text-2xl);font-weight:600;line-height:1.2;letter-spacing:-.01em;color:var(--ink);text-wrap:balance;}

.hx-block{margin-top:28px;}
.hx-block-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin-bottom:10px;}
.hx-block-head a,.hx-block-head button{font-size:var(--text-xs);color:var(--accent-strong);}
.hx .hx-label{margin:0 0 10px;font:600 var(--text-2xs)/1.3 var(--font-mono);letter-spacing:.08em;text-transform:uppercase;color:var(--ink-faint);}
.hx-block-head .hx-label{margin:0;}

.hx-acts{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;}
.hx-act{display:flex;align-items:center;gap:10px;min-height:44px;box-sizing:border-box;padding:8px 12px;border-radius:var(--radius-md);
  background:var(--paper-raised);box-shadow:var(--elev-1);color:var(--ink);text-decoration:none;font-size:var(--text-sm);font-weight:500;
  transition:box-shadow var(--dur-2) var(--ease-standard);}
.hx-act svg{flex:none;width:18px;height:18px;color:var(--accent-strong);stroke-width:var(--icon-stroke);}
.hx-act:hover{box-shadow:var(--elev-2);}
.hx-act:focus-visible{outline:2px solid var(--focus);outline-offset:2px;}
.hx-drop{margin:10px 0 0;font-size:var(--text-xs);line-height:1.5;color:var(--ink-faint);}
/* Nothing is dropped on a phone. */
@media (hover:none){ .hx-drop{display:none;} }

/* The launcher: every application as its mark and its name, as a phone's
   home screen shows them. The mark sits on a square faintly of its own
   hue; the name is the only word. */
.hx-launch .hx-label a{color:inherit;text-decoration:none;}
.hx-launch .hx-label a:hover{color:var(--ink);}
.hx-launch .hx-label a:focus-visible{outline:2px solid var(--focus);outline-offset:2px;border-radius:var(--radius-sm);}
.hx-launch + .hx-launch{margin-top:20px;}
.hx-apps{list-style:none;display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:12px 8px;margin:0;padding:0;}
.hx-app{position:relative;display:flex;flex-direction:column;align-items:center;gap:7px;box-sizing:border-box;min-height:44px;
  padding:4px 2px 2px;border-radius:var(--radius-md);color:var(--ink-soft);text-decoration:none;font-size:var(--text-xs);line-height:1.25;}
.hx-app .hx-ico{width:52px;height:52px;box-sizing:border-box;border-radius:var(--radius-lg);border:1px solid var(--rule);
  background:var(--paper-raised);transition:border-color var(--dur-2) var(--ease-standard);}
.hx-app .hx-ico svg{width:26px;height:26px;}
@supports (color: color-mix(in oklab, red 10%, blue)){
  .hx-app .hx-ico{background:color-mix(in oklab, currentColor 8%, var(--paper-raised));
    border-color:color-mix(in oklab, currentColor 20%, var(--rule));}
}
.hx-app-name{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:center;}
.hx-app:hover{color:var(--ink);}
.hx-app:hover .hx-ico{border-color:var(--rule-strong);}
.hx-app:focus-visible{outline:2px solid var(--focus);outline-offset:2px;}
.hx-app .hx-lock{position:absolute;top:0;left:calc(50% + 16px);width:18px;height:18px;box-sizing:border-box;border-radius:50%;
  background:var(--paper);border:1px solid var(--rule);}
.hx-app .hx-lock svg{width:11px;height:11px;}

.hx-rows{list-style:none;margin:0;padding:0;border-radius:var(--radius-md);background:var(--paper-raised);box-shadow:var(--elev-1);}
.hx-rows li + li{border-top:1px solid var(--rule);}
.hx-row{display:grid;grid-template-columns:120px minmax(0,1fr) auto;align-items:center;gap:12px;min-height:44px;padding:6px 14px;
  color:var(--ink);text-decoration:none;font-size:var(--text-sm);}
.hx-row:hover{background:var(--paper-inset);}
.hx-row:focus-visible{outline:2px solid var(--focus);outline-offset:-2px;}
.hx-row-when{font:500 var(--text-2xs)/1.3 var(--font-mono);letter-spacing:.04em;color:var(--ink-faint);font-variant-numeric:tabular-nums;}
.hx-row-when.is-late{color:var(--danger);}
.hx-row-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.hx-row-from{font-size:var(--text-2xs);color:var(--ink-faint);}

.hx-today .boot-continue .boot-grid{grid-template-columns:repeat(4,minmax(0,1fr));}
.hx-today .home-wait{text-align:left;padding:22px 24px 18px;}
.hx-today .home-wait > p{margin-left:0;}
.hx-links{display:flex;flex-wrap:wrap;gap:4px 18px;margin:0;font-size:var(--text-sm);}
.hx-links a{display:inline-flex;align-items:center;min-height:32px;color:var(--accent-strong);}
.hx-links a:hover{color:var(--ink);}
.hx-links a:focus-visible{outline:2px solid var(--focus);outline-offset:2px;border-radius:var(--radius-sm);}
/* A finger needs the full 44px; a pointer is happy with the tighter row. */
@media (pointer:coarse){ .hx-links{column-gap:20px;} .hx-links a{min-height:44px;} }
.hx-act:active{box-shadow:var(--elev-1);background:var(--paper-inset);}
.hx-today .os-footer{max-width:none;margin:36px 0 0;padding-left:0;padding-right:0;}

/* ------------------------------------------------------------ narrower */

@media (max-width:1100px){
  .hx-acts{grid-template-columns:repeat(2,minmax(0,1fr));}
}
@media (max-width:900px){
  .hx{grid-template-columns:232px minmax(0,1fr);}
  .hx-today{padding:22px 22px 0;}
  .hx-today .boot-continue .boot-grid{grid-template-columns:repeat(2,minmax(0,1fr));}
}

/* A phone: the main area takes the width and the sidebar is a drawer, on
   the left, over it. Without a script the sidebar follows Today down the
   page instead, still a list of links. */
@media (max-width:760px){
  .hx{display:flex;flex-direction:column-reverse;}
  .hx-page .os-topbar{padding:6px 10px;}
  .hx-today{padding:18px 16px 0;}
  .hx-title{font-size:var(--text-xl);}
  .hx-row{grid-template-columns:minmax(0,1fr) auto;row-gap:2px;}
  .hx-row-when{grid-column:1 / -1;}
  .hx-item,.hx-tool{min-height:44px;display:flex;align-items:center;}
  .hx-apps{grid-template-columns:repeat(auto-fill,minmax(72px,1fr));}

  :root.hx-js .hx-page{height:100vh;height:100dvh;display:flex;flex-direction:column;overflow:hidden;}
  :root.hx-js .hx{flex:1 1 auto;min-height:0;display:flex;flex-direction:row;}
  :root.hx-js .hx-main{flex:1 1 auto;}
  :root.hx-js .hx-side{position:fixed;left:0;top:0;bottom:0;z-index:10001;width:min(320px,86vw);
    transform:translateX(-102%);visibility:hidden;box-shadow:var(--elev-2);
    transition:transform var(--dur-4-out) var(--ease-exit),visibility 0s linear var(--dur-4-out);}
  :root.hx-js.hx-drawer-open .hx-side{transform:none;visibility:visible;
    transition:transform var(--dur-4) var(--ease-standard),visibility 0s;}
  :root.hx-js .hx-side-x{display:grid;place-items:center;flex:none;width:44px;height:44px;padding:0;border:0;border-radius:var(--radius-md);
    background:none;color:var(--ink-soft);cursor:pointer;}
  :root.hx-js .hx-side-x svg{width:18px;height:18px;}
  :root.hx-js .hx-side-x:focus-visible{outline:2px solid var(--focus);outline-offset:-2px;}
  .hx-find-input{height:44px;font-size:var(--text-md);}
  .hx-scrim{position:fixed;inset:0;z-index:10000;background:oklch(0 0 0 / 0.45);}
  .hx-scrim[hidden]{display:none;}
  :root.hx-js .hx-menu{display:inline-flex;align-items:center;gap:6px;flex:none;min-height:44px;margin-left:-6px;padding:0 10px;
    border:0;border-radius:var(--radius-md);background:none;color:var(--ink);font:inherit;font-size:var(--text-sm);font-weight:600;cursor:pointer;}
  :root.hx-js .hx-menu svg{width:20px;height:20px;}
  :root.hx-js .hx-menu:focus-visible{outline:2px solid var(--focus);outline-offset:-2px;}
  .hx-head{min-height:44px;padding:0 8px;}
  /* On a phone an application opens as a page of its own (home-shell.js),
     so the window's row of tabs only ever held Today: a third bar under
     the site's two. It goes while it holds one tab, and the row with the
     Menu button scrolls away with Today rather than staying pinned over
     it, as the site's bar does on every other page's content. */
  .hx-tabs:not(:has(.hx-tab + .hx-tab)){display:none;}
  :root.hx-js .hx-main:has(> #hxToday:not([hidden])){overflow-y:auto;overscroll-behavior-y:contain;}
  :root.hx-js #hxToday{flex:none;overflow:visible;}
  a.hx-tab,.hx-tab-link{min-height:44px;}
  .hx-tab-x{width:44px;height:44px;}
  .hx-acts{grid-template-columns:minmax(0,1fr) minmax(0,1fr);}
}
@media (max-width:400px){
  .hx-tab{max-width:160px;}
}

/* Less motion: nothing slides or fades. */
:root[data-motion="none"] .hx-side,:root[data-motion="none"] .hx-item,:root[data-motion="none"] .hx-app .hx-ico,
:root[data-motion="none"] .hx-act,:root[data-motion="none"] .hx-group > summary::after{transition:none;}
@media (prefers-reduced-motion:reduce){
  .hx-side,.hx-item,.hx-app .hx-ico,.hx-act,.hx-group > summary::after{transition:none;}
}
