/* harrhys.com · mobile.css · phones in portrait (under 700px) and touch screens. Loaded last, so it wins.
   Follows the usual mobile guidance: primary navigation in a bottom tab bar within thumb reach; tap targets at least
   44px (Apple HIG / WCAG 2.5.5, comfortably above the 24px WCAG 2.2 AA minimum); inputs at 16px so iOS doesn't zoom
   on focus; menus as bottom sheets with a grab handle, swipe/tap-outside/Esc to close; content clear of the notch and
   home indicator (safe areas); no hover-only effects on touch. */
:root{--tabh:58px;--safe-b:env(safe-area-inset-bottom,0px)}
html{-webkit-tap-highlight-color:transparent;-webkit-text-size-adjust:100%;text-size-adjust:100%}/* iPhones otherwise enlarge text in landscape */
a,button,select,summary,label,input[type=checkbox]{touch-action:manipulation}/* no double-tap-zoom delay */
.tabbar,.msheet,.mscrim,.tkfab,.tkviewpick,.ck-cancel,.hamb{display:none}

/* ---------- any touch screen ---------- */
@media (hover:none){
  /* hover lifts get "stuck" after a tap on touch screens: off, with a press effect instead */
  .tool:hover,.bitem:hover,.lnk:hover,.pchip:hover{transform:none!important;box-shadow:var(--shadow)!important}
  .tmenu a:hover{transform:none}
  button:active,.btn:active,.tool:active,.bitem:active,.tb:active,.tkv:active,.lnk:active{transform:scale(.97)}
  .kbonly{display:none}/* "Press N", "Ctrl K"… mean nothing without a keyboard */
}
@media (pointer:coarse),(max-width:699px){
  /* iOS zooms the page into any field under 16px when you tap it */
  input:not([type=checkbox]):not([type=radio]):not([type=range]):not(#ckq),select,textarea{font-size:16px!important}
  /* comfortable tap targets */
  button,.btn,select,input[type=text],input[type=search],input[type=number],input[type=date],input[type=datetime-local],summary{min-height:44px}
  .btn{display:inline-flex;align-items:center;justify-content:center;gap:6px}/* taller link-buttons keep their text centred */
  .chk{min-height:44px}.chk input,.td-sub input{width:22px;height:22px}
  .tkcp-r{min-height:52px}.tkcp-pin{width:40px!important;height:40px!important}
  .td-chk{width:28px;height:28px}
  .evdel{min-width:44px}
}

/* ---------- phones turned sideways: keep content clear of the notch at the side (safe areas) ---------- */
@media (max-width:999px){
  .topin,.page{padding-left:max(18px,env(safe-area-inset-left,0px));padding-right:max(18px,env(safe-area-inset-right,0px))}
  .page-todo .tkd{right:max(12px,env(safe-area-inset-right,0px))}
}

/* ---------- phones in portrait ---------- */
@media (max-width:699px){
  /* slim one-row header (sections move to the bottom tab bar) */
  .topin{display:flex!important;align-items:center;justify-content:space-between;gap:8px;padding:6px 14px!important}
  .topin .tl{display:none!important}
  .topin .logo{margin:0;min-height:44px}.topin .themebtn{width:44px;height:44px;margin-left:auto}
  .hamb{display:grid;place-items:center;flex:none;width:44px;height:44px;padding:0;border:1px solid var(--line);border-radius:3px;background:var(--card);color:var(--ink)}
  .hamb svg{width:22px;height:22px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round}
  .page{padding:18px 16px 28px;overflow-wrap:break-word}
  .kv td,.out,pre{overflow-wrap:anywhere}/* long values (records, addresses, hashes) wrap rather than overflowing *//* a long word or link wraps rather than widening the page */
  /* the drifting background lights are sized to the screen's long side, so on a phone one blob fills the top of the
     screen and reads as a smudge; they're also six animated blended layers (battery). Off on phones; the grid stays */
  #bgfx{display:none}
  h1{font-size:1.9rem}
  footer{display:none}/* sync status + sign out live in the More sheet */
  body{padding-bottom:calc(var(--tabh) + var(--safe-b))}

  /* bottom tab bar */
  .tabbar{display:grid;grid-template-columns:repeat(5,1fr);position:fixed;left:0;right:0;bottom:0;z-index:40;height:calc(var(--tabh) + var(--safe-b));padding-bottom:var(--safe-b);
    background:var(--card);/* solid fallback for browsers without color-mix (older iOS), which would otherwise leave it see-through */
    background:color-mix(in srgb,var(--card) 92%,transparent);-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);border-top:1px solid var(--line)}
  .tb{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;min-height:var(--tabh);padding:6px 2px 4px;margin:0;
    border:0;border-radius:0;background:none;color:var(--muted);font:600 .7rem "Exo 2",sans-serif;letter-spacing:.02em;text-decoration:none}
  .tb:hover{box-shadow:none;background:none}
  .tabbar,.tkfab{-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}/* no text selection / iOS long-press pop-up */
  /* not on show until the page is: hidden behind the splash and the loading cover (iOS can draw the frosted tab bar
     over them), then faded in */
  .tabbar{transition:opacity .35s ease}
  html.splash .tabbar,html.fw .tabbar,html.splash .tkfab,html.fw .tkfab{opacity:0;pointer-events:none}
  /* on-screen keyboard up: the tab bar and floating buttons step aside (see mobile.js) */
  html.kb-open .tabbar,html.kb-open .tkfab,html.kb-open #tkbulk{display:none}
  html.kb-open body{padding-bottom:0}
  .tb svg{width:24px;height:24px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
  .tb[data-sect=more] circle{fill:currentColor;stroke:none}
  .tb.on,.tb[aria-expanded=true]{color:var(--sage-d)}
  .tb.on::before{content:"";position:absolute;top:0;left:32%;right:32%;height:3px;border-radius:0 0 3px 3px;background:var(--sage)}
  .tbb{position:absolute;top:5px;left:calc(50% + 6px);min-width:18px;height:18px;padding:0 5px;border-radius:9px;background:var(--danger);color:#fff;font:700 .68rem/18px "Exo 2",sans-serif;text-align:center}
  /* toasts / undo sit above the tab bar */
  .toast{bottom:calc(var(--tabh) + var(--safe-b) + 12px)}
  #undobar{bottom:calc(var(--tabh) + var(--safe-b) + 60px)}

  /* bottom sheets + backdrop */
  .mscrim{display:block;position:fixed;inset:0;z-index:44;background:rgba(0,0,0,.45);opacity:0;transition:opacity .25s ease}
  .mscrim.on{opacity:1}.mscrim[hidden]{display:none}
  /* no overflow:hidden page lock: on iPhone that jumps the page back to the top. Sheets keep their own scrolling
     (overscroll-behavior), and the backdrop simply doesn't scroll */
  .mscrim{touch-action:none}
  .msheet{display:block;position:fixed;left:0;right:0;bottom:0;z-index:45;max-height:85vh;max-height:85dvh;overflow:auto;overscroll-behavior:contain;padding:6px 12px calc(14px + var(--safe-b));
    background:var(--card);border-radius:4px 4px 0 0;box-shadow:0 -12px 40px rgba(0,0,0,.35);transform:translateY(105%);transition:transform .3s var(--ease)}
  .msheet.open{transform:none}.msheet[hidden]{display:none}
  .msh-grab{width:40px;height:5px;border-radius:3px;background:var(--line);margin:4px auto 10px;column-span:all}
  .msh-links{display:grid;gap:2px}
  .msh-links a,.msh-row{display:flex;align-items:center;gap:14px;width:100%;min-height:52px;padding:0 10px;border:0;border-radius:3px;background:none;text-decoration:none;font:600 1.02rem "Exo 2",sans-serif;color:var(--ink);text-align:left}
  .msh-links a>span,.msh-row>span{width:34px;height:34px;flex:none;display:grid;place-items:center;border-radius:3px;background:var(--sage-l);color:var(--sage-d);font:400 .8rem "Share Tech Mono",ui-monospace,monospace}
  .msh-links a[aria-current]{background:color-mix(in srgb,var(--sage) 12%,transparent);color:var(--sage-d)}
  .msh-row{margin-top:6px;border-top:1px solid var(--line);border-radius:0}.msh-row:hover{box-shadow:none}.msh-row b{flex:1;font-weight:600}
  .msh-sw{position:relative;width:46px;height:28px;border-radius:14px;background:var(--line);transition:background .2s}
  .msh-sw::after{content:"";position:absolute;top:3px;left:3px;width:22px;height:22px;border-radius:50%;background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.35);transition:transform .22s var(--ease)}
  .msh-row[aria-pressed=true] .msh-sw{background:var(--sage-d)}.msh-row[aria-pressed=true] .msh-sw::after{transform:translateX(18px)}
  .msh-sync{display:flex;align-items:center;gap:6px;padding:10px 10px 0;border-top:1px solid var(--line);color:var(--muted);font-size:.88rem}
  .msh-sync a{margin-left:auto;min-height:44px;display:inline-flex;align-items:center;padding:0 6px;color:var(--ink)}

  /* Tools menu → bottom sheet */
  /* two columns as a grid (a multi-column layout with a height limit spills sideways and shows a scrollbar) */
  .tmenu{display:grid;grid-template-columns:1fr 1fr;align-items:start;gap:0 10px;columns:auto;
    left:0!important;right:0!important;top:auto!important;bottom:0;width:auto!important;max-height:85vh;max-height:85dvh;overflow-x:hidden;border-radius:4px 4px 0 0;
    padding:6px 12px calc(14px + var(--safe-b));z-index:45;opacity:1;transform:translateY(105%);transition:transform .3s var(--ease);overscroll-behavior:contain;box-shadow:0 -12px 40px rgba(0,0,0,.35)}
  .tmenu.open{transform:none}
  .tmenu a{min-height:44px}.tmenu .mall,.tmenu .msh-grab{grid-column:1/-1}.tmenu .mall{margin-top:6px}

  /* search → drops from the top, with a Cancel button */
  #cmdk{padding:0}
  .ck-panel{width:100%;border-radius:0 0 4px 4px;padding-top:env(safe-area-inset-top)}
  .ck-bar{padding:10px 12px 10px 16px}
  .ck-cancel{display:inline-flex;align-items:center;flex:none;min-height:40px;padding:0 10px;border:0;background:none;color:var(--sage-d);font-weight:600}
  #ckr{max-height:calc(78vh - 70px);max-height:calc(78dvh - 70px)}
  .ck-item{min-height:52px}.ck-foot{display:none}

  /* ---- To do ---- */
  .page-todo .lede,.page-todo .td-hint{display:none}
  .page-todo .spread{align-items:center}
  .tkviews{display:none!important}
  .tkviewpick{display:flex;flex-direction:column;gap:4px}.tkviewpick select{min-height:48px;font-weight:600}
  .tkside{padding:10px}
  .tkset>summary{display:list-item;padding:0;line-height:44px}/* min-height 44px already: extra padding left a gap under the label */
  .tkbar2 input[type=search]{order:3;flex:1 1 100%;max-width:none}
  /* ticket cards: roomier, with bigger controls */
  .tkr{padding:14px 14px 14px 52px!important;touch-action:pan-y;-webkit-touch-callout:none}/* pan-y: the browser scrolls vertically, sideways drags go to the swipe actions */
  .tk td.c-sel{padding:14px 12px!important}.tk .c-sel input{width:22px;height:22px}
  .tk-subj{font-size:1.02rem}
  .tk .c-act .ghost{min-height:44px;padding:0 16px}
  .tkp{min-height:40px}
  /* floating "+" to raise a ticket, above the tab bar */
  .tkfab{display:grid;place-items:center;position:fixed;right:16px;bottom:calc(var(--tabh) + var(--safe-b) + 16px);z-index:30;width:56px;height:56px;padding:0;border:0;border-radius:0;clip-path:polygon(0 0,calc(100% - 12px) 0,100% 12px,100% 100%,12px 100%,0 calc(100% - 12px));
    background:var(--sage);color:#04140B;transition:opacity .2s,transform .2s}
  .tkfab svg{width:26px;height:26px;fill:none;stroke:currentColor;stroke-width:2.4;stroke-linecap:round}
  .tkfab:focus-visible{clip-path:none}/* the angled-corner clip would otherwise hide the keyboard focus ring */
  body:has(#tkbulk.show) .tkfab,html.sheet-open .tkfab,body:has(.page-todo .tkd) .tkfab{opacity:0;pointer-events:none;transform:scale(.8)}
  /* bulk actions: full width just above the tab bar */
  /* fixed two-row layout (count + close on top, the four actions in equal columns below), so it never rewraps
     differently as the count changes width */
  #tkbulk{left:8px!important;right:8px;width:auto;max-width:none;bottom:calc(var(--tabh) + var(--safe-b) + 8px);transform:translateY(18px);
    display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px 6px;padding:8px 10px}
  #tkbulk .tkbulk-n{grid-column:1/4;grid-row:1;align-self:center;font-variant-numeric:tabular-nums}
  #tkbulk .tkbulk-x{grid-column:4;grid-row:1;justify-self:end;min-width:44px}
  #tkbulk .tkbulk-sep{display:none}
  #tkbulk>button:not(.tkbulk-x),#tkbulk>select{grid-row:2;width:100%;min-width:0;padding:0 6px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  #tkbulk.show{transform:none}
  /* ticket panel → full-screen sheet: sticky header (close), one column of fields, actions pinned to the bottom */
  .page-todo .tkd{position:fixed!important;inset:0!important;width:auto!important;max-height:none!important;z-index:50;border-radius:0;padding:0 16px;gap:14px;
    background:var(--card)!important;-webkit-backdrop-filter:none!important;backdrop-filter:none!important;box-shadow:none;overscroll-behavior:contain}

  .tkd-head{position:sticky;top:0;z-index:2;margin:0 -16px;padding:calc(16px + env(safe-area-inset-top)) 16px 10px;background:var(--card);border-bottom:1px solid var(--line)}
  .tkd-head::before{content:"";position:absolute;top:calc(5px + env(safe-area-inset-top));left:50%;width:40px;height:5px;margin-left:-20px;border-radius:3px;background:var(--line)}
  .tkd-x{min-width:44px;min-height:44px;font-size:1.2rem}
  .tkd-grid{grid-template-columns:minmax(0,1fr)}
  /* the panel only ever moves up and down: no sideways scrolling or sideways drags in it (pinch-zoom still works), and
     nothing in it can be wider than it. iOS draws the date picker and long unbroken text (links) wider than Chrome does */
  .page-todo .tkd{overflow-x:hidden!important;overflow-y:auto;touch-action:pan-y pinch-zoom;overflow-wrap:anywhere}
  .page-todo .tkd input,.page-todo .tkd select,.page-todo .tkd textarea{min-width:0;max-width:100%;box-sizing:border-box}
  .page-todo .tkd input[type=datetime-local]{display:block;width:100%}
  .tkd-acts{order:99;position:sticky;bottom:0;z-index:2;margin:auto -16px 0;padding:10px 16px calc(10px + var(--safe-b));background:var(--card);border-top:1px solid var(--line);
    display:flex;gap:8px}
  .tkd-acts button{flex:1;min-height:48px;padding:0 8px}.tkd-acts .primary{flex:1.6}
  /* column chooser → bottom sheet */
  #tkcolpop{left:0!important;right:0!important;top:auto!important;bottom:0!important;width:auto!important;max-height:85vh!important;max-height:85dvh!important;border-radius:4px 4px 0 0;padding-bottom:var(--safe-b);overscroll-behavior:contain}
  #tkcolpop .tkcp-b{overscroll-behavior:contain}
  #tkcolpop::before{content:"";display:block;flex:none;width:40px;height:5px;margin:8px auto 0;border-radius:3px;background:var(--line)}
  #tkcolpop:popover-open{animation:mshIn .3s var(--ease)}
  @keyframes mshIn{from{transform:translateY(100%)}}

  /* tool forms: the text box gets its own full-width line instead of being squeezed */
  .panel>.row>input[type=text],.panel>.row>input[type=search],.panel>.row>input:not([type]){flex:1 1 100%!important}
  .panel>.row>button.primary{flex:1}
}
/* installed app (Home Screen) on iPhone: iOS frosts a band under the status bar that fades out a little below the
   status-bar height down the screen (measured from a real screenshot: smeared at the top, crisp from ~107pt).
   Push anything that sits at the very top below that band, so the frost only ever covers plain background.
   Where there's no status-bar overlap (inset 0) this adds nothing. */
@media (display-mode:standalone) and (max-width:699px){
  header.top{padding-top:calc(env(safe-area-inset-top,0px) + 14px)}
  .tkd-head{padding-top:calc(env(safe-area-inset-top,0px) + 24px)}
  .tkd-head::before{top:calc(env(safe-area-inset-top,0px) + 10px)}
  .ck-panel{padding-top:calc(env(safe-area-inset-top,0px) + 14px)}
}
/* ---------- phone animations (patterns from native apps: sheets that spring up, a navigation stack that slides,
   swipe actions on list items, small "pop" feedback). All off with "reduce motion" (below). ---------- */
@media (max-width:699px){
  .msheet,.tmenu{transition:transform .4s var(--mac)!important}/* iOS-like spring for sheets */
  /* ticket panel: slides up when opened, back down when closed */
  .page-todo .tkd.fresh{animation:mSheetUp .42s var(--mac)}
  .page-todo .tkd.closing{transform:translateY(100%)!important;transition:transform .24s cubic-bezier(.4,0,1,1)!important}
  @keyframes mSheetUp{from{transform:translateY(100%)}}
  /* navigation stack: into a detail page from the right, back out from the left */
  .page.m-push{animation:mPush .36s var(--mac)}.page.m-pop{animation:mPop .36s var(--mac)}
  .page.m-push>*,.page.m-pop>*{animation:none!important}
  @keyframes mPush{from{transform:translateX(34px);opacity:0}}
  @keyframes mPop{from{transform:translateX(-34px);opacity:0}}
  /* swipe actions on ticket cards: the strip underneath shows what letting go will do */
  .tk tbody{position:relative}
  .tkr.swiping{-webkit-user-select:none;user-select:none;position:relative;z-index:1;background:var(--card)!important;box-shadow:0 6px 20px rgba(0,0,0,.35)}
  .swbg{position:absolute;left:0;right:0;z-index:0;display:flex;align-items:center;padding:0 22px;font:700 .95rem "Exo 2",sans-serif;color:#04140B;background:var(--sage)}
  .swbg[data-dir=l]{background:var(--blue);justify-content:flex-end}
  .swbg .sw-l,.swbg[data-dir=l] .sw-r{display:none}.swbg[data-dir=l] .sw-l{display:block}
  .swbg span{opacity:.55;transform:scale(.88);transition:opacity .15s,transform .25s var(--spring)}
  .swbg.sw-go span{opacity:1;transform:scale(1.1)}
  /* small feedback */
  .tk .c-sel input:checked,.chk input:checked{animation:pop .32s var(--spring)}
  .tkbulk-n.bump{animation:bump .32s var(--spring)}@keyframes bump{40%{transform:scale(1.16)}}
  .tkfab svg{transition:transform .3s var(--spring)}.tkfab:active svg{transform:rotate(90deg)}
  .tb.on::before{animation:tbIn .34s var(--spring)}@keyframes tbIn{from{transform:scaleX(0)}}
  .tb.on svg{animation:tbHop .42s var(--spring)}@keyframes tbHop{35%{transform:translateY(-3px) scale(1.12)}}
}
@media (max-width:699px) and (prefers-reduced-motion:reduce){
  .page-todo .tkd.fresh,.page.m-push,.page.m-pop,.tkbulk-n.bump,.tb.on::before,.tb.on svg,.tk .c-sel input:checked,.chk input:checked,#tkcolpop:popover-open{animation:none!important}
  .msheet,.tmenu,.mscrim,.tkfab,.page-todo .tkd.closing{transition:none!important}}
