:root{ --ink:#131E1B; --ink-2:#20302B; --ink-3:#2C3F39; --slate:#5C6B65; --slate-2:#8A968F; --line:#DCDFD9; --paper:#F4F5F2; --card:#FFFFFF; --verdigris:#2E6E60; --verdigris-soft:#E4EFEB; --brass:#A87F3C; --brass-soft:#F6EEDF; --violet:#5F55A0; --steel:#54646D; --steel-soft:#E9EDEF; --late:#AE4034; --late-soft:#F8E9E7; --r:10px; } *{box-sizing:border-box;-webkit-tap-highlight-color:transparent} html,body{margin:0;padding:0} body{background:var(--paper);color:var(--ink);font-family:"IBM Plex Sans",system-ui,sans-serif; font-size:15px;line-height:1.45;-webkit-font-smoothing:antialiased} button{font:inherit;color:inherit;border:0;background:none;cursor:pointer} textarea,input,select{font:inherit} :focus-visible{outline:2px solid var(--verdigris);outline-offset:2px;border-radius:4px} .app{max-width:560px;margin:0 auto;min-height:100vh;display:flex;flex-direction:column} header{background:var(--ink);color:#fff;padding:16px 18px 14px;position:relative} .eyebrow{font-family:"IBM Plex Mono",monospace;font-size:10px;letter-spacing:.18em; text-transform:uppercase;color:var(--slate-2);margin:0 0 3px} h1{font-family:"IBM Plex Sans Condensed",sans-serif;font-weight:700;font-size:23px;margin:0;text-transform:uppercase} /* One flex row of equal boxes. Positioning each icon with its own `right` offset gave uneven gaps, because the glyphs are not the same width — and a mix of emoji and text glyphs also renders at different sizes and colours. Matched SVGs in fixed boxes solve both. */ .tools{position:absolute;top:12px;right:12px;display:flex;gap:2px} .tool{ width:36px;height:36px;display:flex;align-items:center;justify-content:center; border-radius:8px;color:#7A8A83;transition:color .12s,background .12s } .tool svg{ width:19px;height:19px;fill:none;stroke:currentColor;stroke-width:1.6; stroke-linecap:round;stroke-linejoin:round } .tool:hover{color:#DDE4E0;background:rgba(255,255,255,.07)} .tool:active{background:rgba(255,255,255,.12)} /* the admin and report pages still use a single back/settings link */ .gear{position:absolute;top:14px;right:14px;color:#7A8A83;font-size:19px;padding:6px} .counts{display:flex;gap:7px;margin-top:13px;flex-wrap:wrap} .count{font-family:"IBM Plex Mono",monospace;font-size:11px;padding:5px 9px;border-radius:100px; background:var(--ink-3);color:#D7DEDA;display:flex;align-items:center;gap:6px} .count b{font-weight:600;color:#fff} .count.warn{background:#43221D;color:#F0BDB6} .count.warn b{color:#fff} .swatch{width:8px;height:8px;border-radius:50%} .swatch.out{background:var(--brass)} .swatch.in{background:var(--verdigris)} .swatch.res{background:var(--steel)} .scroll{flex:1;overflow-y:auto;padding-bottom:80px} .board{background:var(--ink-2);padding:14px 14px 20px;min-height:60vh} /* Cabinets wrap onto as many rows as they need. A horizontal scroller hides cabinets behind the edge, on the one screen you look at most. */ .cabs{ display:grid;grid-template-columns:repeat(auto-fit,minmax(96px,1fr)); gap:6px;margin-bottom:11px } .cab{ padding:8px 10px;border-radius:8px;background:var(--ink);border:1px solid var(--ink-3); text-align:left;min-width:0 } .cab[aria-pressed="true"]{background:#fff;border-color:#fff} .cab .cn{ display:block;font-family:"IBM Plex Sans Condensed",sans-serif;font-weight:700; font-size:12.5px;text-transform:uppercase;color:#CBD5D0;letter-spacing:.01em; white-space:nowrap;overflow:hidden;text-overflow:ellipsis } .cab[aria-pressed="true"] .cn{color:var(--ink)} .cab .cs{ display:block;font-family:"IBM Plex Mono",monospace;font-size:9.5px;color:#7A8A83; margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis } .cab[aria-pressed="true"] .cs{color:var(--slate)} .cab .cs .o{color:var(--brass)} /* wider screens fit more per row without the tiles becoming huge */ @media (min-width:460px){ .cabs{grid-template-columns:repeat(auto-fit,minmax(112px,1fr))} .cab{padding:9px 12px} .cab .cn{font-size:13px} .cab .cs{font-size:10px} } .where{font-size:11.5px;color:#8A968F;margin:0 0 12px;padding-left:2px;line-height:1.5} .filters{display:flex;gap:6px;margin-bottom:14px;flex-wrap:wrap} .chip{font-size:12px;padding:6px 11px;border-radius:100px;background:transparent;color:#9FADA7;border:1px solid var(--ink-3)} .chip[aria-pressed="true"]{background:#fff;color:var(--ink);border-color:#fff;font-weight:500} .rail{margin-bottom:15px} .rail-label{font-family:"IBM Plex Mono",monospace;font-size:10px;letter-spacing:.14em;text-transform:uppercase; color:var(--slate-2);padding-bottom:6px;margin-bottom:9px;border-bottom:1px solid var(--ink-3); display:flex;justify-content:space-between;align-items:baseline;gap:10px} .rail-label span{color:#6E7D77;flex:none} .pegs{display:grid;grid-template-columns:repeat(auto-fill,minmax(46px,1fr));gap:7px} .peg{aspect-ratio:1;display:flex;flex-direction:column;align-items:center;justify-content:center; font-family:"IBM Plex Mono",monospace;font-size:11.5px;font-weight:500;border:1.5px solid transparent; position:relative;transition:transform .1s} .peg:active{transform:scale(.93)} /* shape = what it is, fill = where it is. Both now come from the type record rather than being hardcoded for two kinds. */ .peg.shape-circle{border-radius:50%} .peg.shape-rounded{border-radius:5px} .peg.shape-square{border-radius:0} .peg.st-in{background:var(--k,var(--verdigris));color:#fff;border-color:var(--k,var(--verdigris))} .peg.st-reserve{background:#48585F;color:#C6D2D7;border-color:#5E7079} .peg.st-out{background:transparent;color:var(--brass);border-color:var(--brass)} .peg.st-lost,.peg.st-retired{background:transparent;color:#6E7D77;border-color:#4A5A54;border-style:dashed} .peg.late{color:#E8907F;border-color:var(--late);border-width:2px} .peg .flag{position:absolute;top:-2px;right:-2px;width:9px;height:9px;border-radius:50%; background:var(--late);border:1.5px solid var(--ink-2)} .peg .memo{position:absolute;bottom:-1px;right:2px;font-size:8px;opacity:.85} .peg small{font-size:8px;opacity:.75;margin-top:1px} .legend{display:flex;gap:13px;flex-wrap:wrap;margin-top:4px;font-family:"IBM Plex Mono",monospace; font-size:10px;color:#8A968F} .legend i{display:inline-block;width:11px;height:11px;margin-right:5px;vertical-align:-2px;border:1.5px solid} .lg-in{background:var(--verdigris);border-color:var(--verdigris);border-radius:50%} .lg-out{border-color:var(--brass);border-radius:50%} .lg-res{background:#48585F;border-color:#5E7079;border-radius:50%} .lg-late{border-color:var(--late);border-radius:50%;border-width:2px} .lg-kind{border-radius:3px} .pane{padding:14px} .search,.field{width:100%;padding:11px 13px;border:1px solid var(--line);border-radius:var(--r); background:var(--card);font-size:15px;margin-bottom:12px} .search:focus,.field:focus{outline:none;border-color:var(--verdigris);box-shadow:0 0 0 3px var(--verdigris-soft)} .row{display:flex;align-items:center;gap:12px;width:100%;text-align:left;background:var(--card); border:1px solid var(--line);border-radius:var(--r);padding:11px 13px;margin-bottom:7px} .row:active{background:#FAFBF9} .row.late{border-color:#E4BDB6;background:#FEFAF9} .badge{flex:none;width:42px;height:42px;display:flex;align-items:center;justify-content:center; font-family:"IBM Plex Mono",monospace;font-size:11px;font-weight:600;border:1.5px solid} .badge.shape-circle{border-radius:50%} .badge.shape-rounded{border-radius:6px} .badge.shape-square{border-radius:0} .badge.st-in{background:var(--k,var(--verdigris));border-color:var(--k,var(--verdigris));color:#fff} .badge.st-reserve{background:var(--steel);border-color:var(--steel);color:#fff} .badge.st-out{border-color:var(--brass);color:var(--brass)} .badge.st-lost,.badge.st-retired{border-color:#B9BEB8;color:#909790;border-style:dashed} .badge.person{background:var(--paper);border-color:var(--line);color:var(--slate);border-radius:50%; font-family:"IBM Plex Sans Condensed",sans-serif;font-size:14px} .badge.door{background:var(--ink);border-color:var(--ink);color:#fff;border-radius:8px; font-family:"IBM Plex Sans Condensed",sans-serif;font-size:15px} .row-main{flex:1;min-width:0} .row-t{font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis} .row-s{font-size:12.5px;color:var(--slate);white-space:nowrap;overflow:hidden;text-overflow:ellipsis} .row-s .held{color:var(--brass);font-weight:500} .row-s .od{color:var(--late);font-weight:500} .row-n{flex:none;font-family:"IBM Plex Mono",monospace;font-size:11px;color:var(--slate-2); text-align:right;line-height:1.3} .dots{display:flex;gap:3px;justify-content:flex-end;margin-top:3px;flex-wrap:wrap;max-width:70px} .dot{width:9px;height:9px;border-radius:50%;border:1.5px solid} .dot.in{background:var(--k,var(--verdigris));border-color:var(--k,var(--verdigris))} .dot.out{border-color:var(--brass)} .dot.reserve{background:var(--steel);border-color:var(--steel)} .dot.lost,.dot.retired{border-color:#C3C8C2;border-style:dashed} .sec{font-family:"IBM Plex Mono",monospace;font-size:10px;letter-spacing:.14em;text-transform:uppercase; color:var(--slate);margin:18px 0 8px;padding-bottom:5px;border-bottom:1px solid var(--line)} .sec:first-child{margin-top:0} .empty{text-align:center;padding:32px 22px;color:var(--slate);font-size:14px;border:1px dashed var(--line); border-radius:var(--r);background:var(--card)} .log{background:var(--card);border:1px solid var(--line);border-radius:var(--r);overflow:hidden} .log-row{display:flex;gap:11px;padding:11px 13px;border-bottom:1px solid var(--line);align-items:baseline} .log-row:last-child{border-bottom:0} .log-d{font-family:"IBM Plex Mono",monospace;font-size:10.5px;color:var(--slate-2);flex:none;width:52px} .log-b{flex:1;font-size:13.5px;min-width:0} .log-tag{font-family:"IBM Plex Mono",monospace;font-weight:500} .memo-line{color:var(--slate);font-size:12px;font-style:italic;margin-top:2px} .dir{font-family:"IBM Plex Mono",monospace;font-size:9.5px;letter-spacing:.1em;text-transform:uppercase; padding:2px 6px;border-radius:3px;flex:none} .dir.out{background:var(--brass-soft);color:var(--brass)} .dir.in{background:var(--verdigris-soft);color:var(--verdigris)} .dir.late{background:var(--late-soft);color:var(--late)} .scrim{position:fixed;inset:0;background:rgba(10,18,16,.5);z-index:40;opacity:0;pointer-events:none;transition:opacity .2s} .scrim.on{opacity:1;pointer-events:auto} .sheet{position:fixed;left:50%;bottom:0;transform:translate(-50%,100%);width:100%;max-width:560px; max-height:90vh;overflow-y:auto;z-index:50;background:var(--paper);border-radius:16px 16px 0 0; transition:transform .24s cubic-bezier(.32,.72,0,1);padding:0 16px calc(20px + env(safe-area-inset-bottom))} .sheet.on{transform:translate(-50%,0)} .grab{width:34px;height:4px;background:#C8CEC8;border-radius:3px;margin:9px auto 4px} .sheet h2{font-family:"IBM Plex Sans Condensed",sans-serif;font-weight:700;font-size:24px;margin:8px 0 2px;text-transform:uppercase} .sheet .sub{color:var(--slate);font-size:13.5px;margin:0 0 14px} .status-line{padding:11px 13px;border-radius:var(--r);margin-bottom:14px;font-size:13.5px} .status-line.out{background:var(--brass-soft);color:#6E5223} .status-line.in{background:var(--verdigris-soft);color:#1D4A40} .status-line.reserve{background:var(--steel-soft);color:#33454D} .status-line.late{background:var(--late-soft);color:#7A2C23} .status-line.lost,.status-line.retired{background:#F0F0EE;color:var(--slate)} .status-line b{font-weight:600} .facts{background:var(--card);border:1px solid var(--line);border-radius:var(--r);margin-bottom:14px} .fact{display:flex;justify-content:space-between;gap:14px;padding:9px 13px;border-bottom:1px solid var(--line);font-size:13.5px} .fact:last-child{border-bottom:0} .fact dt{color:var(--slate);margin:0;flex:none} .fact dd{margin:0;text-align:right;font-weight:500;min-width:0} .mono{font-family:"IBM Plex Mono",monospace;font-size:12.5px} .tiny{display:block;font-weight:400;font-size:11.5px;color:var(--slate-2)} .actions{display:flex;gap:8px;margin-bottom:16px} .btn{flex:1;padding:13px;border-radius:var(--r);font-weight:600;font-size:15px;text-align:center} .btn:active{filter:brightness(.92)} .btn:disabled{opacity:.45} .btn-p{background:var(--verdigris);color:#fff} .btn-o{background:var(--brass);color:#fff} .btn-d{background:var(--late);color:#fff} .btn-g{background:var(--card);color:var(--ink);border:1px solid var(--line)} .note-box{background:var(--card);border:1px solid var(--line);border-radius:var(--r);padding:11px 13px;margin-bottom:14px} .note-box textarea{width:100%;border:0;resize:vertical;min-height:52px;font-size:14px;background:transparent} .note-box textarea:focus{outline:none} .note-box .cap{font-family:"IBM Plex Mono",monospace;font-size:9.5px;letter-spacing:.12em; text-transform:uppercase;color:var(--slate-2);margin-bottom:6px;display:block} .mini{padding:8px 14px;border-radius:8px;font-size:13px;font-weight:600;background:var(--ink);color:#fff} .sigpad{background:#fff;border:1px solid var(--line);border-radius:var(--r);margin-bottom:8px;position:relative;overflow:hidden} .sigpad canvas{display:block;width:100%;height:150px;touch-action:none} .sigpad .hint{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:#B7BEB8;font-size:13px;pointer-events:none} .sigline{position:absolute;left:16px;right:16px;bottom:30px;border-bottom:1px dashed #D4D9D3;pointer-events:none} .sigshot{background:#fff;border:1px solid var(--line);border-radius:8px;padding:5px;margin-top:6px} .sigshot img{display:block;width:100%;max-width:220px} .due-opts{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:14px} .due{padding:8px 12px;border-radius:100px;border:1px solid var(--line);background:var(--card);font-size:13px;color:var(--slate)} .due[aria-pressed="true"]{background:var(--ink);color:#fff;border-color:var(--ink);font-weight:500} .tabs{position:fixed;bottom:0;left:50%;transform:translateX(-50%);width:100%;max-width:560px; background:rgba(255,255,255,.94);backdrop-filter:blur(12px);border-top:1px solid var(--line); display:flex;z-index:30;padding-bottom:env(safe-area-inset-bottom)} .tab{flex:1;padding:9px 2px 11px;text-align:center;color:var(--slate-2);font-size:10px;font-weight:500} .tab .ic{display:flex;align-items:center;justify-content:center;margin-bottom:3px} .tab .ic svg{ width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:1.6; stroke-linecap:round;stroke-linejoin:round } .tab[aria-selected="true"]{color:var(--verdigris)} .note{font-size:11.5px;color:var(--slate);text-align:center;padding:14px 20px 4px;line-height:1.5} .toast{position:fixed;left:50%;bottom:78px;transform:translate(-50%,20px);background:var(--ink);color:#fff; padding:10px 18px;border-radius:100px;font-size:13.5px;z-index:60;opacity:0;pointer-events:none; transition:opacity .2s,transform .2s;max-width:90vw;text-align:center} .toast.on{opacity:1;transform:translate(-50%,0)} .toast.err{background:var(--late)} /* ---- admin ---- */ .admin{max-width:760px;margin:0 auto;padding-bottom:40px} .adm-nav{display:flex;gap:6px;flex-wrap:wrap;padding:12px 14px 0} .adm-nav button{padding:8px 13px;border-radius:100px;border:1px solid var(--line); background:var(--card);font-size:13px;color:var(--slate)} .adm-nav button[aria-pressed="true"]{background:var(--ink);color:#fff;border-color:var(--ink);font-weight:500} .grid2{display:grid;grid-template-columns:1fr 1fr;gap:10px} .lab{display:block;font-family:"IBM Plex Mono",monospace;font-size:9.5px;letter-spacing:.12em; text-transform:uppercase;color:var(--slate-2);margin-bottom:4px} .card{background:var(--card);border:1px solid var(--line);border-radius:var(--r);padding:14px;margin-bottom:12px} .card h3{font-family:"IBM Plex Sans Condensed",sans-serif;text-transform:uppercase;font-size:16px;margin:0 0 10px} table{width:100%;border-collapse:collapse;font-size:13.5px} th{text-align:left;font-family:"IBM Plex Mono",monospace;font-size:9.5px;letter-spacing:.1em; text-transform:uppercase;color:var(--slate-2);padding:6px 8px;border-bottom:1px solid var(--line)} td{padding:7px 8px;border-bottom:1px solid var(--line)} tr:last-child td{border-bottom:0} .warnbox{background:var(--late-soft);border:1px solid #E4BDB6;color:#7A2C23; border-radius:var(--r);padding:12px 14px;margin-bottom:12px;font-size:13.5px} @media (prefers-reduced-motion:reduce){*{transition:none!important}} /* ---- login --------------------------------------------------------------- Full-bleed dark, with the peg board itself as the backdrop — the same motif the app opens onto, so the first screen already looks like the thing it protects. */ .login{ min-height:100vh;min-height:100dvh;display:flex;align-items:center;justify-content:center; padding:24px;background:var(--ink);position:relative;overflow:hidden } #pegfield{position:absolute;inset:0;width:100%;height:100%;opacity:.28;pointer-events:none} .login-card{ position:relative;z-index:1;width:100%;max-width:330px;text-align:center } .login-mark{ width:54px;height:54px;margin:0 auto 18px;border-radius:50%; border:2px solid var(--verdigris);display:flex;align-items:center;justify-content:center; background:rgba(46,110,96,.14) } .login-mark svg{width:26px;height:26px;stroke:var(--verdigris);fill:none;stroke-width:1.9; stroke-linecap:round;stroke-linejoin:round} .login-card .eyebrow{margin-bottom:5px} .login-card h1{color:#fff;font-size:26px;margin-bottom:8px} .login-sub{color:#8A968F;font-size:13.5px;margin:0 0 22px} .pw-wrap{position:relative;margin-bottom:10px} .pw{ width:100%;padding:14px 46px 14px 16px;border-radius:var(--r); background:var(--ink-2);border:1px solid var(--ink-3);color:#fff;font-size:16px; font-family:"IBM Plex Mono",monospace;letter-spacing:.08em;text-align:center; transition:border-color .15s,box-shadow .15s } .pw::placeholder{color:#5E6E68;letter-spacing:0;font-family:"IBM Plex Sans",sans-serif} .pw:focus{outline:none;border-color:var(--verdigris);box-shadow:0 0 0 3px rgba(46,110,96,.25)} .pw-toggle{ position:absolute;right:6px;top:50%;transform:translateY(-50%); width:36px;height:36px;border-radius:8px;color:#7A8A83;font-size:15px; display:flex;align-items:center;justify-content:center } .pw-toggle:hover{color:#B9C4BF} .login .btn-p{width:100%;padding:14px} .login-err{ color:#E8907F;font-size:13px;min-height:19px;margin:12px 0 0; opacity:0;transition:opacity .15s } .login-err.on{opacity:1} .shake{animation:shake .32s cubic-bezier(.36,.07,.19,.97)} @keyframes shake{ 10%,90%{transform:translateX(-2px)} 20%,80%{transform:translateX(4px)} 30%,50%,70%{transform:translateX(-7px)} 40%,60%{transform:translateX(7px)} } .login-foot{ position:absolute;bottom:22px;left:0;right:0;text-align:center;z-index:1; color:#4E5E58;font-size:11px;font-family:"IBM Plex Mono",monospace;letter-spacing:.05em; padding:0 24px } @media (prefers-reduced-motion:reduce){.shake{animation:none}} /* ---- reports -------------------------------------------------------------- Screen styling stays close to the app; print styling drops to plain black on white, because these end up in a folder or taped inside a cabinet. */ .report{max-width:900px;margin:0 auto;padding:0 18px 60px} .rep-bar{ display:flex;gap:8px;flex-wrap:wrap;align-items:center; padding:14px 0;position:sticky;top:0;background:var(--paper);z-index:5; border-bottom:1px solid var(--line);margin-bottom:20px } .rep-bar select,.rep-bar .mini{margin:0} .rep-bar select{ padding:9px 12px;border:1px solid var(--line);border-radius:8px; background:var(--card);font-size:14px } .rep-head{margin-bottom:22px} .rep-head h1{font-size:26px;margin:0 0 4px} .rep-meta{ font-family:"IBM Plex Mono",monospace;font-size:11px;color:var(--slate); letter-spacing:.03em } .rep-stats{display:flex;gap:20px;flex-wrap:wrap;margin:14px 0 0;padding:12px 0; border-top:1px solid var(--line);border-bottom:1px solid var(--line)} .rep-stat b{display:block;font-family:"IBM Plex Sans Condensed",sans-serif; font-size:22px;line-height:1.1} .rep-stat span{font-size:11px;color:var(--slate);text-transform:uppercase;letter-spacing:.08em; font-family:"IBM Plex Mono",monospace} .rep-group{margin-bottom:26px;break-inside:avoid} .rep-group h2{ font-family:"IBM Plex Sans Condensed",sans-serif;font-size:17px;text-transform:uppercase; margin:0 0 2px;padding-bottom:5px;border-bottom:2px solid var(--ink) } .rep-group .who{font-size:12.5px;color:var(--slate);margin:0 0 9px} table.rep{width:100%;border-collapse:collapse;font-size:13px} table.rep th{ text-align:left;font-family:"IBM Plex Mono",monospace;font-size:9.5px;letter-spacing:.1em; text-transform:uppercase;color:var(--slate);padding:5px 7px;border-bottom:1px solid var(--ink) } table.rep td{padding:6px 7px;border-bottom:1px solid var(--line);vertical-align:top} table.rep tr{break-inside:avoid} table.rep .num{font-family:"IBM Plex Mono",monospace;font-weight:600;white-space:nowrap} table.rep .od{color:var(--late);font-weight:600} .tick{display:inline-block;width:13px;height:13px;border:1.4px solid #556;border-radius:3px} .sig-block{ break-inside:avoid;border:1px solid var(--line);border-radius:8px;padding:10px; margin-bottom:10px;background:var(--card) } .sig-block img{display:block;max-width:230px;max-height:80px} .sig-cap{font-family:"IBM Plex Mono",monospace;font-size:10px;color:var(--slate);margin-bottom:6px} .sign-off{margin-top:34px;display:flex;gap:40px;flex-wrap:wrap;break-inside:avoid} .sign-off div{flex:1;min-width:200px} .sign-line{border-bottom:1px solid var(--ink);height:38px;margin-bottom:5px} .sign-lab{font-size:11px;color:var(--slate);font-family:"IBM Plex Mono",monospace} @media print{ @page{size:A4;margin:14mm 12mm} html,body{background:#fff!important;color:#000!important} .rep-bar,.no-print{display:none!important} .report{max-width:none;padding:0} .rep-head h1{font-size:20px} table.rep{font-size:10.5pt} table.rep thead{display:table-header-group} /* repeat headers across pages */ .rep-group{page-break-inside:avoid} a{text-decoration:none;color:#000} .rep-stat b{font-size:16pt} } /* ---- access request form ------------------------------------------------- The only page an outsider may ever see, so it is calmer and plainer than the rest of the app: no peg board, no counts, nothing about the building. */ .req-page{min-height:100vh;background:var(--paper)} .req-top{background:var(--ink);color:#fff;padding:26px 20px 24px} .req-top .inner{max-width:520px;margin:0 auto} .req-top h1{color:#fff;font-size:24px;margin:2px 0 10px} .req-top p{color:#9FADA7;font-size:13.5px;line-height:1.55;margin:0;max-width:46ch} .req-wrap{max-width:520px;margin:0 auto;padding:20px 16px 60px} .req-field{margin-bottom:16px} .req-field .lab{margin-bottom:6px} .req-field input[type=text],.req-field textarea{ width:100%;padding:12px 13px;border:1px solid var(--line);border-radius:var(--r); background:var(--card);font-size:16px } .req-field textarea{min-height:86px;resize:vertical} .req-field input:focus,.req-field textarea:focus{ outline:none;border-color:var(--verdigris);box-shadow:0 0 0 3px var(--verdigris-soft) } .req-hint{font-size:12px;color:var(--slate);margin:5px 0 0} .areas{display:flex;flex-direction:column;gap:7px} .area{ display:flex;align-items:center;gap:11px;padding:12px 13px;background:var(--card); border:1px solid var(--line);border-radius:var(--r);cursor:pointer;font-size:15px } .area:has(input:checked){border-color:var(--verdigris);background:var(--verdigris-soft)} .area input{width:19px;height:19px;accent-color:var(--verdigris);flex:none} .pin-row{display:flex;gap:10px;align-items:flex-start} .pin-row .req-field{flex:1;margin-bottom:0} .req-msg{ padding:12px 14px;border-radius:var(--r);font-size:13.5px;margin-bottom:14px;display:none } .req-msg.on{display:block} .req-msg.bad{background:var(--late-soft);color:#7A2C23} .req-done{ text-align:center;padding:52px 20px;max-width:400px;margin:0 auto } .req-done .tickmark{ width:60px;height:60px;border-radius:50%;background:var(--verdigris-soft); color:var(--verdigris);display:flex;align-items:center;justify-content:center; font-size:30px;margin:0 auto 18px } .req-done h2{font-family:"IBM Plex Sans Condensed",sans-serif;text-transform:uppercase; font-size:22px;margin:0 0 8px} .req-done p{color:var(--slate);font-size:14px;line-height:1.6;margin:0 0 22px} .req-foot{ text-align:center;font-size:11.5px;color:var(--slate-2);margin-top:26px; font-family:"IBM Plex Mono",monospace } .hp{position:absolute;left:-9999px;width:1px;height:1px;opacity:0} /* request inbox inside the app */ .req-card{ background:var(--card);border:1px solid var(--line);border-left:3px solid var(--brass); border-radius:var(--r);padding:12px 13px;margin-bottom:8px } .req-card.done{border-left-color:var(--line);opacity:.62} .req-card h4{margin:0 0 2px;font-size:15px;font-weight:600} .req-card .meta{font-family:"IBM Plex Mono",monospace;font-size:10.5px;color:var(--slate-2)} .req-card .areas-line{font-size:13px;color:var(--brass);font-weight:500;margin:6px 0 0} .req-card .detail{font-size:13.5px;color:var(--slate);margin:6px 0 0;line-height:1.5} .badge-count{ background:var(--brass);color:#fff;border-radius:100px;padding:1px 7px; font-size:11px;font-weight:600;margin-left:7px;font-family:"IBM Plex Sans",sans-serif } /* ---- board fills its column, so the dark panel never stops mid-screen ---- */ .scroll{display:flex;flex-direction:column} .board{flex:1 0 auto} .board .note{color:#77857F} /* --------------------------------------------------------------------------- Desktop. Same markup, different shape: the bottom tab bar becomes a side rail and the content gets the width it was already capable of using. --------------------------------------------------------------------------- */ @media (min-width:900px){ body{background:var(--paper)} .app{ max-width:1120px;min-height:100vh; display:grid; grid-template-columns:212px minmax(0,1fr); grid-template-rows:auto minmax(0,1fr); border-left:1px solid var(--line);border-right:1px solid var(--line) } header{grid-column:1 / -1;grid-row:1;padding:20px 26px 18px} header h1{font-size:26px} .tools{top:18px;right:18px} .gear{top:20px} /* side rail */ .tabs{ position:static;transform:none;grid-column:1;grid-row:2; max-width:none;width:auto;flex-direction:column;align-items:stretch; background:transparent;backdrop-filter:none; border-top:0;border-right:1px solid var(--line); padding:16px 12px 24px;gap:2px; justify-content:flex-start;align-content:flex-start } .tab{ /* the mobile bar sets flex:1 so five tabs share the width; in a vertical rail that makes each item stretch to fill the whole column height */ flex:0 0 auto; display:flex;align-items:center;gap:11px; padding:11px 13px;border-radius:8px;text-align:left;font-size:14px; transition:background .12s } .tab:hover{background:#EDEFEA} .tab .ic{margin:0;width:20px;flex:none} .tab[aria-selected="true"]{background:var(--verdigris-soft);color:var(--verdigris);font-weight:600} .scroll{grid-column:2;grid-row:2;padding-bottom:0;overflow-y:auto} .board{padding:20px 22px 26px} .pane{padding:20px 22px 40px;max-width:720px} /* more pegs per row when there is room for them */ .pegs{grid-template-columns:repeat(auto-fill,minmax(52px,1fr));gap:8px} .cabs{grid-template-columns:repeat(auto-fit,minmax(132px,1fr));gap:8px} /* the bottom sheet becomes a centred dialog */ .sheet{ top:50%;bottom:auto;left:50%; transform:translate(-50%,-46%) scale(.97); width:min(560px,92vw);max-height:86vh;border-radius:14px; box-shadow:0 24px 70px rgba(10,18,16,.32); padding:0 22px 24px;opacity:0;transition:opacity .16s,transform .16s } .sheet.on{transform:translate(-50%,-50%) scale(1);opacity:1} .grab{display:none} .sheet h2{margin-top:20px} .toast{bottom:26px} /* wider forms and tables have room to breathe */ .admin{max-width:1000px} .grid2{gap:14px} } @media (min-width:900px) and (prefers-reduced-motion:reduce){ .sheet{transition:none} } /* type swatch in the admin list */ .kind-chip{ display:inline-flex;align-items:center;gap:8px;padding:5px 10px;border:1px solid var(--line); background:var(--card);font-size:13px;margin:0 6px 6px 0 } .kind-dot{width:15px;height:15px;border:1.5px solid;flex:none}