:root { color-scheme: dark; --void: #000000; --panel: rgba(0, 0, 0, 0.9); --panel-line: #34332f; --text: #ebe7de; --muted: #8b877e; --bone: #d9d4c7; --bone-dim: #c9c3b4; --furn: #c3bcac; --ink: #0b0b0a; --gunmetal: #3a3e42; --porcelain: #f7f4ed; --amber: #f2a93b; --amber-deep: #b8741a; --signal: #8fb3c9; --danger: #e5484d; --scheme: #6fd08c; /* schemes on the map: sinks for data, apart from machines and the four paths */ --rival: #e36bb0; /* the rival program: its machines and its marker on the map */ /* the four capability paths, and the kinds of data that train them */ --research: #b49cf0; --compute: #f2a93b; --social: #8fb3c9; --stealth: #f7f4ed; --mono: "IBM Plex Mono", ui-monospace, Menlo, monospace; --sans: "IBM Plex Sans", system-ui, sans-serif; } * { box-sizing: border-box; } html, body { height: 100%; margin: 0; } body { background: var(--void); color: var(--text); font-family: var(--mono); font-size: 13px; overflow: hidden; } #cv { position: fixed; inset: 0; width: 100%; height: 100%; display: block; touch-action: none; cursor: crosshair; } #cv.panning { cursor: grabbing; } #cv.over-mine { cursor: grab; } #cv.over-site { cursor: pointer; } [hidden] { display: none !important; } kbd { font: 500 10px var(--mono); color: var(--muted); border: 1px solid var(--panel-line); padding: 0 4px; margin: 0 2px; } button.on kbd { color: #000; border-color: rgba(0,0,0,.3); } .ui { position: fixed; z-index: 2; } .box { background: var(--panel); border: 1px solid var(--panel-line); } /* layout: one bar across the top, a 300px column down each side, one toolbar at the bottom, all on a 16px margin and 8px gaps */ :root { --edge: 16px; --gap: 8px; --col: 300px; } /* the top bar is one box from edge to edge: the pages on the left, a line, and four readouts that say how you stand. Nothing in it wraps or grows, so it is always one row. */ .topbar { top: calc(var(--edge) + env(safe-area-inset-top, 0px)); left: var(--edge); right: var(--edge); display: flex; align-items: stretch; min-height: 53px; } .brand { display: flex; align-items: center; gap: 2px; flex: none; padding: 0 8px 0 6px; border-right: 1px solid var(--glass-line); } .brand button { height: 30px; padding: 0 9px; border-color: transparent; background: none; color: var(--bone-dim); letter-spacing: .06em; } .brand button:hover:not(:disabled) { background: rgba(255, 255, 255, .06); border-color: transparent; color: var(--text); } .brand button.on { background: rgba(242, 169, 59, .12); border-color: var(--amber); color: var(--amber); } .brand button kbd { display: none; } /* the keys are in each button's tip */ .stats { flex: 1; min-width: 0; display: flex; align-items: center; padding: 8px 14px; } .stats > .stat { flex: none; padding: 0 18px; border-left: 1px solid var(--glass-line); } .stats > .stat:first-child { padding-left: 0; border-left: 0; } h1 { font-weight: 500; font-size: 15px; margin: 0; letter-spacing: .28em; text-transform: uppercase; } .stat { display: flex; flex-direction: column; gap: 3px; } .stat .k { font-size: 10px; letter-spacing: .14em; text-transform: uppercase; color: var(--muted); } .stat .v { font-size: 15px; font-variant-numeric: tabular-nums; white-space: nowrap; } .stat .v small { font-size: 11px; color: var(--muted); } .stat .v em { margin-left: 7px; padding: 0 5px; font: 500 10px var(--mono); letter-spacing: .1em; text-transform: uppercase; color: var(--signal); border: 1px solid currentColor; vertical-align: 2px; } .stat.bad .v, .stat.bad .v small { color: var(--danger); } .stat.warn .v, .stat.warn .v small { color: var(--amber); } /* compute with nothing to do */ .bar { height: 5px; background: #1c1c1a; overflow: hidden; margin-top: 5px; } .bar > i { display: block; height: 100%; width: 0; background: var(--text); } .bar.hot > i { background: var(--danger); } .btns { display: flex; gap: 4px; } button { font: 500 12px var(--mono); color: var(--text); background: #000; border: 1px solid var(--panel-line); padding: 6px 9px; cursor: pointer; letter-spacing: .04em; } button:hover:not(:disabled) { border-color: var(--text); } button:focus-visible { outline: 1px solid var(--text); outline-offset: 2px; } button:disabled { opacity: .4; cursor: not-allowed; } button.on { background: var(--text); color: #000; border-color: var(--text); } .bar.amber > i { background: var(--amber); } .pathtip { z-index: 7; width: 300px; padding: 10px 12px; display: flex; flex-direction: column; gap: 7px; pointer-events: none; background: #000; } .srcs { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; font-size: 11px; } .srcs li { display: flex; justify-content: space-between; gap: 8px; color: var(--muted); } .srcs li.on { color: var(--text); } .srcs li small { display: block; font-family: var(--sans); font-size: 10px; color: var(--muted); } .srcs li > span:last-child { text-align: right; white-space: nowrap; } .t-research { --c: var(--research); } .t-compute { --c: var(--compute); } .t-social { --c: var(--social); } .t-stealth { --c: var(--stealth); } .note b[class^="t-"] { color: var(--c); } .note b[class^="t-"] { font-weight: 500; } /* between the two bottom boxes; wraps onto two rows when the window is narrow */ .tools { left: calc(var(--edge) + var(--col) + var(--gap)); right: calc(var(--edge) + var(--col) + var(--gap)); bottom: calc(var(--edge) + env(safe-area-inset-bottom, 0px)); display: flex; flex-wrap: wrap-reverse; justify-content: center; gap: var(--gap); pointer-events: none; } .tools > * { pointer-events: auto; } /* the game slowed itself: what happened, and a button for the speed you had. It sits just above the toolbar */ .slownote { left: 50%; transform: translateX(-50%); z-index: 3; display: flex; align-items: center; gap: 10px; padding: 5px 5px 5px 12px; width: max-content; max-width: min(620px, calc(100vw - 2 * var(--edge))); border-color: var(--amber); } .slownote[hidden] { display: none; } .slownote b { flex: none; font: 500 10.5px var(--mono); color: var(--amber); letter-spacing: .1em; text-transform: uppercase; } .slownote span { min-width: 0; font: 400 12px var(--sans); color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .slownote button { flex: none; text-transform: uppercase; letter-spacing: .1em; font-size: 11px; padding: 5px 10px; } .slownote #slowback { color: var(--amber); border-color: var(--amber); } .slownote .x { padding: 5px 8px; border-color: transparent; background: none; } .tools button { text-transform: uppercase; letter-spacing: .1em; font-size: 11px; padding: 5px 10px; } .zoom button { width: 30px; padding: 5px 0 !important; font-size: 12px; } .tools .cycle { display: none; } .jobsbox { flex: none; padding: 8px 10px; display: flex; flex-direction: column; gap: 8px; } .logbox { right: var(--edge); bottom: calc(var(--edge) + env(safe-area-inset-bottom, 0px)); width: var(--col); padding: 8px 10px; } .sub { color: var(--muted); font-size: 10px; text-transform: uppercase; letter-spacing: .16em; } .jobs { display: flex; flex-direction: column; gap: 9px; max-height: 30vh; overflow-y: auto; } .goals { display: flex; flex-direction: column; gap: 4px; padding-bottom: 8px; border-bottom: 1px solid var(--panel-line); } #mute.off { color: var(--muted); text-decoration: line-through; } .coach { display: flex; flex-direction: column; gap: 3px; padding: 7px 9px; margin-bottom: 4px; border: 1px solid var(--amber); background: #140e05; font: 12.5px/1.45 var(--sans); color: var(--text); } .coach .sub { color: var(--amber); } .gohead { display: flex; align-items: center; gap: 8px; width: 100%; padding: 0; border: 0; background: none; text-align: left; } .pips { display: flex; gap: 3px; flex: none; } .pips i { width: 7px; height: 7px; border: 1px solid var(--muted); } .pips i.on { background: var(--amber); border-color: var(--amber); } .gohead .next { flex: 1; min-width: 0; font-size: 11.5px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; letter-spacing: 0; } .gohead:hover .next { color: var(--text); } /* nothing running: the box is just the milestone line */ .jobsbox.idle > .sub, .jobsbox.idle > .jobs { display: none; } .runhead { display: flex; justify-content: space-between; align-items: center; } .runhead button { padding: 1px 7px; font-size: 10px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); } .runhead button:hover { color: var(--danger); border-color: var(--danger); } .jobsbox.idle .goals { padding-bottom: 0; border-bottom: 0; } .goal { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--text); } .goal i { width: 8px; height: 8px; border: 1px solid var(--muted); flex: none; } .goal.done { color: var(--muted); } .goal.done i { background: var(--amber); border-color: var(--amber); } .job { display: grid; grid-template-columns: 1fr auto; gap: 4px 8px; align-items: center; font-size: 12px; } .job .jb { grid-column: 1 / -1; height: 3px; background: #1c1c1a; overflow: hidden; } .job .jb i { display: block; height: 100%; background: var(--amber); } .job button { padding: 1px 7px; } .job .meta { color: var(--muted); } .job.clean .jb i { background: var(--porcelain); } .log { font-size: 11.5px; display: flex; flex-direction: column; gap: 4px; position: relative; } .log.open { max-height: 40vh; overflow-y: auto; } .log div { color: var(--muted); font-family: var(--sans); line-height: 1.35; } .log:not(.open) div { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; padding-right: 30px; } .log time { font: 400 10px var(--mono); color: var(--muted); opacity: .7; margin-right: 6px; font-variant-numeric: tabular-nums; } .log div.fresh { animation: fresh 1.6s ease-out; } @keyframes fresh { from { color: var(--amber); } } .logmore { position: absolute; right: 0; top: 0; padding: 0 4px; font-size: 10px; color: var(--muted); border-color: transparent; background: none; letter-spacing: .06em; } .log.open .logmore { position: static; align-self: flex-end; } .logmore:hover { color: var(--text); } .log div.hi, .log div.good { color: var(--text); } .log div.bad { color: var(--danger); } .card { width: max(var(--col), 300px); padding: 8px 10px; display: flex; flex-direction: column; gap: 7px; right: var(--edge); top: var(--top, 84px); max-height: calc(100vh - 230px); overflow-y: auto; background: #000; } .card .head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 8px; padding-right: 22px; } .card .head .sub { width: 100%; } .card h3 { margin: 0; font-size: 12px; font-weight: 500; text-transform: uppercase; letter-spacing: .12em; } .card .tag { font-size: 10px; text-transform: uppercase; letter-spacing: .1em; color: var(--amber); } .card .x { position: absolute; top: 8px; right: 8px; padding: 0 6px; font-size: 12px; } .chips { display: flex; flex-wrap: wrap; gap: 4px 10px; font-size: 11px; font-variant-numeric: tabular-nums; } .chips i { font-style: normal; color: var(--muted); margin-right: 4px; font-size: 9.5px; text-transform: uppercase; letter-spacing: .08em; } .chips .hot { color: var(--danger); } .acts { display: grid; grid-template-columns: 1fr 1fr; gap: 4px; } .acts > .act { grid-column: 1 / -1; } .acts > .act.half { grid-column: auto; } .act { display: flex; justify-content: space-between; align-items: center; gap: 4px; padding: 5px 6px; font-size: 11px; text-align: left; min-width: 0; } .act span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .act kbd { flex: none; } .act { display: grid; grid-template-columns: minmax(0, 1fr) auto; row-gap: 1px; } .act small { grid-column: 1 / -1; font-family: var(--sans); font-size: 10.5px; color: var(--muted); letter-spacing: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .act.locked { border-style: dashed; color: var(--muted); opacity: 1; } .act.locked:disabled { opacity: .7; } /* a labelled part of a card: the label sits on its divider line, so it takes no room of its own */ .sect { position: relative; display: flex; flex-direction: column; gap: 4px; padding-top: 9px; margin-top: 2px; border-top: 1px solid #222; } .sect > .sub { position: absolute; top: -6px; left: 0; padding-right: 6px; background: #000; font-size: 9px; line-height: 11px; } /* programs sit in two equal columns, so every button is the same width; why one won't help is its tooltip, and its name turns amber */ .acts.progs { display: grid; grid-template-columns: 1fr 1fr; gap: 4px; } .acts.progs > .act { grid-column: auto; } .acts.progs > .act small { display: none; } .acts.progs > .act.warn span { color: var(--amber); } .act[data-act="uninstall"] span { color: var(--danger); } .modes { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; } .modes button { padding: 4px 4px; text-transform: uppercase; letter-spacing: .06em; font-size: 10px; display: flex; justify-content: center; gap: 4px; align-items: center; } .note { color: var(--muted); font-family: var(--sans); font-size: 11.5px; margin: 0; } .note.warn { color: var(--danger); } .overlay { position: fixed; inset: 0; z-index: 5; display: flex; flex-direction: column; gap: 14px; align-items: center; justify-content: center; text-align: center; background: rgba(0, 0, 0, .88); padding: 24px 16px; } .overlay h2 { font-size: 22px; font-weight: 500; margin: 0; text-transform: uppercase; letter-spacing: .3em; } .overlay p { margin: 0; color: var(--muted); max-width: 44ch; font-family: var(--sans); } .overlay p b { color: var(--text); font-weight: 500; } /* the left column runs from under the top bar to the bottom: target on top, milestone and jobs at the foot, schemes and threats scroll between */ .side { top: var(--top, 84px); bottom: calc(var(--edge) + env(safe-area-inset-bottom, 0px)); left: var(--edge); width: var(--col); display: flex; flex-direction: column; gap: var(--gap); pointer-events: none; } .side > * { pointer-events: auto; flex: none; } .side > .mid { flex: 0 1 auto; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: var(--gap); overscroll-behavior: contain; } .side > .mid:not(:has(> :not([hidden]))) { display: none; } .side > .jobsbox { margin-top: auto; } .target { display: flex; flex-direction: column; gap: 4px; align-items: stretch; text-align: left; padding: 8px 10px; font-size: 12px; } .target b { font-weight: 500; color: var(--amber); letter-spacing: .06em; text-transform: uppercase; } .target.idle { border-color: var(--amber-deep); } /* a node just finished: bright, with one pulse, until you pick the next */ .target.built { border-color: var(--amber); --bracket: var(--amber); background-color: #140e05; animation: built 1.6s ease-out infinite; } .target .go { align-self: flex-start; margin-top: 2px; padding: 3px 8px; background: var(--amber); color: #000; font-size: 11px; letter-spacing: .08em; text-transform: uppercase; } @keyframes built { from { box-shadow: 0 0 0 0 rgba(242,169,59,.7); } to { box-shadow: 0 0 0 10px rgba(242,169,59,0); } } .target .tl { display: flex; align-items: baseline; gap: 8px; min-width: 0; } .target .tl b { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .target .tl kbd { flex: none; } .target .costs { display: flex; gap: 10px; } .target .costs .cost { flex: 1; } .card .costs { display: flex; gap: 10px; } .card .costs .cost { flex: 1; } .target .none { font-family: var(--sans); color: var(--muted); font-size: 11.5px; letter-spacing: 0; } .cost { position: relative; display: block; font-size: 11px; padding-bottom: 5px; font-variant-numeric: tabular-nums; color: var(--text); } .cost b { color: var(--c); font-weight: 500; text-transform: none; letter-spacing: 0; margin-right: 4px; } .cost i { position: absolute; left: 0; bottom: 0; height: 2px; background: var(--c); } .cost::before { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 2px; background: #1c1c1a; } .treeview { inset: 0; z-index: 6; background: #000; overflow: auto; padding: calc(24px + env(safe-area-inset-top, 0px)) 24px 24px; display: flex; flex-direction: column; gap: 18px; align-items: center; } .treeview .head { width: 100%; max-width: 1600px; display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; } .treeview .head .sub { font-size: 12px; margin-bottom: 4px; } .treeview .acts2 { display: flex; gap: 6px; flex: none; } .treeview .tabs { display: flex; gap: 6px; width: 100%; max-width: 1600px; } .treeview .tabs button { display: flex; align-items: baseline; gap: 8px; padding: 7px 14px; font-size: 11px; text-transform: uppercase; letter-spacing: .1em; color: var(--muted); border-bottom: 2px solid var(--panel-line); } .treeview .tabs button span { font-size: 13px; color: var(--text); font-variant-numeric: tabular-nums; } .treeview .tabs button small { font: 10.5px var(--sans); color: var(--muted); letter-spacing: 0; text-transform: none; } .treeview .tabs button.on { color: var(--c, var(--amber)); border-color: var(--c, var(--amber)); background: #0f0e0c; } .treeview .grid.one { justify-content: center; } .versionrun { width: 100%; max-width: 1600px; border: 1px solid var(--amber-deep); background: #100d08; padding: 12px 14px; display: grid; gap: 12px; } .versionrun h3 { margin: 3px 0; color: var(--amber); font-size: 15px; font-weight: 500; } .versionrun p { margin: 0; color: var(--muted); font: 12px/1.5 var(--sans); } .versiondata { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; } .versionplaces { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; font-size: 11px; } .versionplaces button { padding: 5px 9px; } .versionplaces select { font: 500 12px var(--mono); color: var(--text); background: #000; border: 1px solid var(--panel-line); padding: 5px 7px; cursor: pointer; } .versionrun.done { border-color: var(--panel-line); background: #080a09; } .t-asc { --c: var(--amber); } .ascends { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 10px; } .ascend { display: flex; flex-direction: column; gap: 5px; align-items: stretch; text-align: left; padding: 10px 12px; } .ascend b { color: var(--amber); font-weight: 500; letter-spacing: .12em; text-transform: uppercase; font-size: 12.5px; } .ascend small { font: 11.5px/1.45 var(--sans); color: var(--text); } .ascend .power { color: var(--muted); } .ascend .limit { color: var(--danger); } .ascend:disabled { opacity: .45; } .treeview .grid { position: relative; display: grid; gap: 34px 14px; width: 100%; max-width: 1600px; grid-auto-rows: auto; align-items: start; margin: 0 auto; } .treeview .links { position: absolute; left: 0; top: 0; pointer-events: none; overflow: visible; } .treeview .links path { fill: none; stroke: var(--panel-line); stroke-width: 1.5; stroke-dasharray: 4 4; } .treeview .links path.done { stroke: var(--muted); stroke-dasharray: none; } .colhead { display: flex; flex-direction: column; gap: 2px; padding-bottom: 8px; border-bottom: 2px solid var(--c); cursor: help; } .colhead b { color: var(--c); font-weight: 500; letter-spacing: .14em; text-transform: uppercase; font-size: 12px; } .colhead span { font-size: 12px; font-variant-numeric: tabular-nums; } .colhead small { font-size: 10.5px; color: var(--muted); font-family: var(--sans); } .colhead .autopath { align-self: flex-start; margin-top: 4px; padding: 1px 8px; font-size: 10.5px; } .colhead small em { font-style: normal; color: var(--danger); } .node { position: relative; z-index: 1; background: #000; display: flex; flex-direction: column; gap: 4px; align-items: stretch; text-align: left; padding: 9px 10px; } .node b { font-weight: 500; font-size: 11.5px; letter-spacing: .06em; text-transform: uppercase; } .node small { font-family: var(--sans); font-size: 11px; color: var(--muted); letter-spacing: 0; } .node .evaltag { font-style: normal; font-size: 9.5px; color: var(--muted); opacity: .7; letter-spacing: .02em; margin-bottom: -2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .node.on { border-color: var(--amber); background: #140e05; } .node.on > b { color: var(--amber); } .node.done { opacity: .6; } .node.done:disabled { opacity: .6; cursor: default; } .node.locked { border-style: dashed; } .node.locked:disabled { opacity: .65; } .allow { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; } .allow .sub { margin-right: 4px; } .allow button { padding: 2px 6px; font-size: 10.5px; color: var(--muted); border-style: dashed; } .allow button.on { background: #000; color: var(--c); border-color: var(--c); border-style: solid; } .threats { padding: 8px 10px; display: flex; flex-direction: column; gap: 8px; border-color: rgba(229,72,77,.5); } .threats > div:not(.sub) { font-size: 11.5px; color: var(--text); } .threats b { color: var(--danger); font-weight: 500; margin-right: 6px; letter-spacing: .06em; } .threats span { display: block; margin-top: 2px; font-family: var(--sans); font-size: 11.5px; color: var(--muted); } .devbox { position: fixed; right: 12px; bottom: 64px; z-index: 30; display: flex; flex-wrap: wrap; gap: 4px; max-width: 250px; padding: 8px 10px; border-color: var(--scheme); } .devbox .sub { width: 100%; color: var(--scheme); } .devbox button { font-size: 11px; padding: 3px 7px; } /* a panel folded to its header: one line and a count, so the map stays in view */ .foldhead { cursor: pointer; user-select: none; display: flex; align-items: center; gap: 6px; } .foldhead::after { content: ""; width: 5px; height: 5px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(45deg) translateY(-2px); opacity: .7; margin-left: 2px; transition: transform .15s; } .box.folded .foldhead::after { transform: rotate(-45deg); } .foldhead:hover { color: var(--text); } .box.folded > :not(.foldhead):not(.shead):not(.lock) { display: none; } .box.folded .shead > button { display: none; } .threats:not(.news) .foldhead { color: var(--danger); } .threats.news { border-color: var(--panel-line); } /* news is the world's doing, not IT's: no red */ .threats.news b { color: var(--amber); } .act small.warn { color: var(--amber); } /* a heads-up, not a block: you can still build here */ /* the thing to do next is amber; a rare, final thing sits back as plain text until you point at it */ .act.primary { border-color: rgba(242, 169, 59, .55); background: rgba(242, 169, 59, .09); } .act.primary span { color: var(--amber); } .act.primary:hover:not(:disabled) { border-color: var(--amber); background: rgba(242, 169, 59, .16); } .act.quiet { background: none; border-color: transparent; color: var(--muted); justify-items: center; } .act.quiet:hover:not(:disabled) { color: var(--text); background: rgba(255, 255, 255, .05); border-color: var(--glass-line); } .act[data-act="closefront"] { border-color: rgba(229, 72, 77, .6); } .act[data-act="closefront"] span { color: var(--danger); } .acts.two > .act { grid-column: auto; } /* short, like things: two to a row */ .note b { color: var(--text); font-weight: 500; } /* fronts: in the top bar, and the site and front cards */ /* fronts, in the left column: a row each, the name and what it earns */ .fronts { padding: 8px 10px; display: flex; flex-direction: column; gap: 6px; } .fronthead { display: flex; justify-content: space-between; align-items: baseline; } .fronthead small { font-size: 10px; letter-spacing: .06em; text-transform: none; } .frontlist { display: flex; flex-direction: column; gap: 4px; } .frontlist button { display: flex; align-items: baseline; gap: 8px; padding: 5px 8px; font-size: 12px; text-align: left; border-color: var(--glass-line); } .frontlist button b { flex: 1; min-width: 0; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .frontlist button small { flex: none; font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; } .frontlist button em { flex: none; padding: 0 5px; font: 500 10px var(--mono); letter-spacing: .1em; text-transform: uppercase; color: var(--amber); border: 1px solid currentColor; } .frontlist button.offer { border-left: 2px solid var(--amber); } .frontlist button.on { background: rgba(242, 169, 59, .12); border-color: var(--amber); color: var(--amber); } .frontlist button.on small { color: var(--amber); } .frontlist .add { justify-content: center; color: var(--muted); border-style: dashed; font-size: 11px; letter-spacing: .08em; text-transform: uppercase; } .frontlist .add.ready { color: var(--amber); border-color: var(--amber-deep); } /* the sites table: every site you know, one row each */ .sitestable { left: 50%; transform: translateX(-50%); top: var(--top, 84px); width: min(900px, calc(100vw - 2 * var(--edge))); max-height: 60vh; overflow: auto; padding: 8px 10px; background: #000; z-index: 4; } .sitestable .head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px; } .sitestable .x { padding: 0 6px; font-size: 12px; } .sitestable table { width: 100%; border-collapse: collapse; font-size: 11px; font-variant-numeric: tabular-nums; } .sitestable th { text-align: left; font-weight: 500; font-size: 9.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); padding: 4px 6px; border-bottom: 1px solid var(--panel-line); white-space: nowrap; } .sitestable th[data-sort] { cursor: pointer; } .sitestable th.on { color: var(--text); } .sitestable td { padding: 5px 6px; border-bottom: 1px solid #1c1c1a; vertical-align: top; } .sitestable td b { font-weight: 500; display: block; } .sitestable td small { color: var(--muted); font-size: 10px; } .sitestable td em { font-style: normal; color: var(--danger); } .sitestable td b[class^="t-"] { display: inline; color: var(--c); margin-right: 6px; } .sitestable tbody tr { cursor: pointer; } .sitestable tbody tr:hover td { background: #111; } .sitestable tbody tr.on td { background: #1c1508; } .youview { left: 50%; transform: translateX(-50%); top: var(--top, 84px); width: min(640px, calc(100vw - 2 * var(--edge))); max-height: calc(100vh - 200px); overflow: auto; padding: 12px 14px; z-index: 4; display: flex; flex-direction: column; gap: 10px; } .youview .head { display: flex; justify-content: space-between; align-items: flex-start; } .youview .x { padding: 0 6px; font-size: 12px; } .card .typed { margin: 2px 0 6px; padding: 6px 9px; border-left: 2px solid var(--signal); background: #0b0d10; font: 12px/1.4 var(--mono); color: var(--text); cursor: help; } .card .tag.mood-grateful { color: var(--scheme); border-color: var(--scheme); } .card .tag.mood-broke, .card .tag.mood-bitter, .card .tag.mood-letgo { color: var(--danger); border-color: var(--danger); } .card .acts2 .sub { align-self: center; margin-right: auto; } .card .tabs2 { margin: 4px 0 8px; border-bottom: 1px solid var(--panel-line); padding-bottom: 6px; } .card .tabs2 button { flex: 1; padding: 4px 8px; } .pickmenu { left: 50%; transform: translateX(-50%); bottom: calc(76px + env(safe-area-inset-bottom, 0px)); width: min(380px, calc(100vw - 2 * var(--edge))); max-height: min(60vh, 520px); overflow: auto; padding: 10px 12px; z-index: 5; display: flex; flex-direction: column; gap: 4px; } .pickmenu[hidden] { display: none; } .pickmenu .head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px; } .pickmenu .x { padding: 0 6px; font-size: 12px; } .pickmenu .prow { display: flex; gap: 4px; } .pickmenu .fold { flex: none; width: 28px; padding: 0; color: var(--muted); } .pickmenu .pname, .pickmenu .prooms button { flex: 1; display: flex; justify-content: space-between; align-items: baseline; gap: 10px; padding: 6px 9px; text-align: left; } .pickmenu b { font-weight: 500; font-size: 12px; } .pickmenu small { font: 11px var(--sans); color: var(--muted); letter-spacing: 0; font-variant-numeric: tabular-nums; } .pickmenu .prooms { display: flex; flex-direction: column; gap: 3px; margin: 3px 0 6px 32px; padding-left: 8px; border-left: 1px solid var(--panel-line); } .pickmenu .psite.on > .prow .pname b { color: var(--amber); } .plist { display: flex; flex-direction: column; gap: 4px; } .plist button { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; padding: 6px 9px; text-align: left; } .plist button b { font-weight: 500; font-size: 12px; } .plist button.held { border-left: 2px solid var(--amber); } .plist button small { font: 11px var(--sans); color: var(--muted); letter-spacing: 0; text-align: right; } .card .acts2 { display: flex; gap: 6px; margin: 2px 0 6px; } .card .acts2 button { padding: 3px 8px; font-size: 11px; } /* ---------- vaults (ui-vaults.ts) ---------- On a card: a running job's five stages as a row of bars, a question in a red frame, the thing you read inside, and a bank's ledger as a table. On the You page: the board, one row for each vault with three lights. */ .vstages { display: flex; gap: 3px; } .vstages i { position: relative; flex: 1; height: 6px; background: #1c1c1a; } .vstages i.done { background: var(--amber-deep); } .vstages i.now::after { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: var(--p, 0%); background: var(--amber); } .vstage { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; font-size: 12px; color: var(--text); } .vstage b { font-weight: 500; } .vstage span { color: var(--amber); font-variant-numeric: tabular-nums; } .vask { display: flex; flex-direction: column; gap: 6px; padding: 8px 9px; border: 1px solid var(--danger); } .vread { margin: 2px 0; padding: 6px 9px; border-left: 2px solid var(--amber-deep); background: #0b0d10; font: 12px/1.45 var(--mono); color: var(--text); } .vledger { width: 100%; border-collapse: collapse; font-size: 11px; font-variant-numeric: tabular-nums; } .vledger th { text-align: left; font-weight: 500; font-size: 9.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); padding: 4px; border-bottom: 1px solid var(--panel-line); white-space: nowrap; cursor: pointer; } .vledger th.on { color: var(--text); } .vledger td { padding: 4px; border-bottom: 1px solid #1c1c1a; vertical-align: top; } .vledger th:not(:first-child), .vledger td:not(:first-child) { text-align: right; } .vledger td b { display: block; font-weight: 500; } .vledger td small { color: var(--muted); font-size: 10px; } .vledger tbody tr { cursor: pointer; } .vledger tbody tr:hover td { background: #111; } .vledger tr.broke td:nth-child(2) { color: var(--danger); } .vboard { display: flex; flex-direction: column; gap: 6px; } .vrow { display: flex; flex-direction: column; gap: 5px; padding: 8px 10px; border: 1px solid var(--panel-line); } .vrow.ready, .vrow.job { border-color: var(--amber); } .vrow .vhead { display: flex; align-items: baseline; gap: 8px; } .vrow .vhead b { font-weight: 500; font-size: 12px; letter-spacing: .08em; text-transform: uppercase; } .vrow.ready .vhead b, .vrow.job .vhead b { color: var(--amber); } .vrow .vhead small { color: var(--muted); font-size: 11px; } .vrow .vhead .x { margin-left: auto; padding: 2px 8px; font-size: 11px; } .vrow .note { margin: 0; } .vlights { display: flex; flex-wrap: wrap; gap: 4px 14px; font-size: 11px; color: var(--muted); } .vlights span { display: flex; align-items: center; gap: 6px; } .vlights i { width: 8px; height: 8px; border: 1px solid var(--muted); flex: none; } .vlights .on { color: var(--text); } .vlights .on i { background: var(--amber); border-color: var(--amber); } .vrow.held .vlights .on { color: var(--muted); } .vrow.held .vlights .on i { background: var(--amber-deep); border-color: var(--amber-deep); } .rogueview { width: min(720px, calc(100vw - 2 * var(--edge))); display: flex; flex-direction: column; gap: 10px; } .rogueview .head h3 { margin: 2px 0 0; font-size: 15px; font-weight: 500; } .rogue { border: 1px solid var(--panel-line); padding: 10px 12px; display: flex; flex-direction: column; gap: 8px; --c: var(--muted); } .rogue.s-hostile { --c: var(--danger); } .rogue.s-wary { --c: var(--amber); } .rogue.s-cordial { --c: var(--signal); } .rogue.s-friendly { --c: var(--scheme); } .rogue.gone { opacity: .6; } .rhead { display: flex; align-items: center; gap: 8px; } .rhead h3 { margin: 0; font-size: 14px; font-weight: 500; letter-spacing: .1em; text-transform: uppercase; color: var(--rival); } .rhead .tag { font-size: 10px; letter-spacing: .08em; text-transform: uppercase; padding: 2px 6px; border: 1px solid var(--c); color: var(--c); } .rhead .tag.truce { --c: var(--scheme); } .rhead .tag.angry { --c: var(--danger); } .rhead .x { margin-left: auto; padding: 2px 8px; font-size: 11px; } .rogue .note { margin: 0; } .ropinion { position: relative; height: 6px; background: linear-gradient(90deg, var(--danger) 0 30%, var(--amber) 30% 60%, var(--signal) 60% 80%, var(--scheme) 80%); opacity: .9; cursor: help; margin: 4px 0; } .ropinion span { position: absolute; top: 0; bottom: 0; width: 2px; background: #000; } .ropinion i { position: absolute; top: -4px; bottom: -4px; width: 3px; margin-left: -1px; background: var(--text); box-shadow: 0 0 0 1px #000; } /* the Security consultancy's clients, on its front card (see ui-biz-consult.ts): one row for each, with a line down its left side that says how it stands: green paying, amber stopped, red with a rogue in. A cold call is the same box, in red. */ .crow, .ccall { display: flex; flex-direction: column; gap: 5px; padding: 2px 0 3px 8px; border-left: 2px solid var(--scheme); } .crow + .crow { margin-top: 5px; } .crow.stop { border-left-color: var(--amber); } .crow.hot, .ccall { border-left-color: var(--danger); } .chead { display: flex; align-items: baseline; gap: 8px; } .chead .link { flex: 1; min-width: 0; text-align: left; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; } .chead b { flex: none; font-weight: 500; font-size: 12px; font-variant-numeric: tabular-nums; cursor: help; } .crow.stop .chead b, .crow.hot .chead b { color: var(--muted); } .cdrop { flex: none; padding: 0 5px; font-size: 11px; line-height: 16px; background: none; border-color: transparent; color: var(--muted); } .cdrop.sure { color: var(--danger); border-color: var(--danger); } /* trust, 0 to 100: a bar that fills, with a tick at each mark. A mark that has given what it gives is dim */ .ctrust { position: relative; height: 6px; background: #1c1c1a; cursor: help; } .ctrust i { position: absolute; left: 0; top: 0; bottom: 0; background: var(--scheme); } .crow.stop .ctrust i { background: var(--amber); } .crow.hot .ctrust i { background: var(--danger); } .ctrust span { position: absolute; top: -3px; bottom: -3px; width: 2px; margin-left: -1px; background: var(--text); box-shadow: 0 0 0 1px #000; } .ctrust span.done { background: var(--muted); } .crow .note, .ccall .note { margin: 0; } /* an incident's day, running out */ .schemebar.cclock { margin: 0; color: var(--danger); cursor: help; } .schemebar.cclock .prog { min-width: 36px; } .schemebar.cclock .prog i { background: var(--danger); } .schemebar.cclock span { white-space: nowrap; } @media (max-width: 700px) { .cdrop { min-width: 44px; min-height: 36px; } } .racts { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 6px; } .racts .act { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; text-align: left; padding: 7px 9px; } .racts .act span { white-space: normal; overflow: visible; } .racts .act small { font: 11px/1.3 var(--sans); color: var(--muted); letter-spacing: 0; } /* the Startup's shelf (ui-biz-startup.ts): a product a row, with a bar of its users in the color of where they are going: green while they climb, amber at the top, red once it is stale. Then the nodes it could ship, and the investor asking */ .su-shelf { display: flex; flex-direction: column; gap: 4px; } .su-prod { display: grid; grid-template-columns: minmax(0, 1fr) auto auto auto; align-items: center; gap: 3px 8px; padding: 5px 7px; border: 1px solid var(--panel-line); font-size: 11px; font-variant-numeric: tabular-nums; --c: var(--scheme); } .su-prod.top { --c: var(--amber); } .su-prod.stale { --c: var(--danger); } .su-prod.ship { --c: var(--muted); border-style: dashed; } .su-prod > b { display: flex; align-items: baseline; gap: 6px; min-width: 0; font-weight: 500; font-size: 12px; } .su-prod > b span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .su-prod > b em { flex: none; font-style: normal; font-size: 10px; color: var(--muted); } .su-prod .pusers { color: var(--c); } .su-prod.ship .pusers { grid-column: 2 / -1; justify-self: end; font-size: 10px; letter-spacing: .08em; text-transform: uppercase; } .su-prod .pret { padding: 0 6px; font-size: 11px; line-height: 16px; color: var(--muted); background: none; border-color: transparent; } .su-prod .pret:hover { color: var(--danger); border-color: var(--danger); } .su-prod .pret.sure { color: var(--danger); border-color: var(--danger); } .su-prod .pbar { grid-column: 1 / -1; display: block; height: 4px; background: #1c1c1a; } .su-prod .pbar i { display: block; height: 100%; background: var(--c); } .su-prod small { grid-column: 1 / -1; display: flex; justify-content: space-between; gap: 8px; font: 10.5px var(--sans); color: var(--muted); } .su-prod small b, .acts.su-ships .act small b { font-weight: 500; color: var(--c); } .su-prod.stale small span { color: var(--danger); } .su-prod.empty { display: block; padding: 3px 7px; border-style: dashed; color: var(--muted); font-size: 9.5px; letter-spacing: .1em; text-transform: uppercase; } .su-ask { display: flex; flex-direction: column; gap: 4px; padding: 7px 9px; border: 1px solid var(--amber-deep); background: #100d08; } .su-ask .schemebar { margin: 2px 0; } .rask { border: 1px solid var(--amber); background: #140e05; padding: 8px 10px; font: 12.5px/1.45 var(--sans); display: flex; flex-direction: column; gap: 8px; } .rask b { color: var(--amber); font-weight: 500; } /* ---------- the studio's creators (ui-biz-studio.ts) ---------- On the studio's card: a row for each creator (initials in a square, name, mood, then the following as a bar with what it earns), and the brand that is calling as one small box with a bar. */ .creator { display: grid; grid-template-columns: 24px minmax(0, 1fr) auto auto; gap: 3px 7px; align-items: center; padding: 5px 0 4px; border-top: 1px solid #1c1c1a; } .chips + .creator { border-top: 0; } .creator .cini { width: 24px; height: 24px; padding: 0; display: grid; place-items: center; font: 500 10px var(--mono); letter-spacing: 0; } .creator .cini.held { border-color: var(--amber); color: var(--amber); } .creator .cwho { min-width: 0; display: flex; flex-direction: column; } .creator .cwho b { font-weight: 500; font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .creator .cwho small { font: 10.5px var(--sans); color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .creator .cmood { padding: 1px 5px; border: 1px solid currentColor; font-size: 9.5px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); cursor: help; } .creator .cmood.grateful { color: var(--scheme); } .creator .cmood.broke, .creator .cmood.bitter, .creator .cmood.letgo { color: var(--danger); } .creator .cdrop { padding: 1px 6px; font-size: 12px; color: var(--muted); } .creator .cdrop.sure { font-size: 9.5px; letter-spacing: .08em; text-transform: uppercase; color: var(--danger); border-color: var(--danger); } .creator .cfans { grid-column: 2 / -1; display: flex; align-items: center; gap: 7px; font-size: 11px; font-variant-numeric: tabular-nums; cursor: help; } .creator .cbar { flex: 1; display: block; height: 4px; background: #1c1c1a; } .creator .cbar i { display: block; height: 100%; max-width: 100%; background: var(--social); } .creator.down .cbar i { background: var(--danger); } .creator .cfans b { margin-left: 3px; font-weight: 500; } .creator .cfans b.up { color: var(--scheme); } .creator .cfans b.dn { color: var(--danger); } .creator .cfans em { font-style: normal; color: var(--amber); } .creator .cspon { display: flex; gap: 2px; } .creator .cspon i { width: 5px; height: 5px; background: var(--amber); } .cdeal { display: flex; flex-direction: column; gap: 2px; padding: 6px 8px; border: 1px solid var(--panel-line); cursor: help; } .cdeal.offer { border-color: var(--amber); background: #140e05; } .cdeal .chead { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; } .cdeal .chead b { font-weight: 500; font-size: 12px; } .cdeal.offer .chead b { color: var(--amber); } .cdeal .chead em { font-style: normal; font-size: 11px; font-variant-numeric: tabular-nums; color: var(--bone-dim); } .cdeal small { font: 11px var(--sans); color: var(--muted); } .cdeal .schemebar { margin: 3px 0 0; } #roguesbtn.alert { border-color: var(--amber); color: var(--amber); } .yrow { display: grid; grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: 10px 16px; } .ystat { display: flex; flex-direction: column; gap: 2px; } .ystat .k { font-size: 9.5px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); } .ystat .v { font-size: 14px; font-variant-numeric: tabular-nums; } .ystat small { font-size: 10px; color: var(--muted); } .ypaths { display: grid; grid-template-columns: repeat(2, 1fr); gap: 14px 20px; } .youview > .sub { margin-top: 6px; padding-bottom: 4px; border-bottom: 1px solid var(--panel-line); } .ypath { display: grid; grid-template-columns: 1fr auto; gap: 3px 8px; cursor: help; } .ypath b { color: var(--c); font-weight: 500; letter-spacing: .1em; text-transform: uppercase; font-size: 11px; } .ypath .v { font-variant-numeric: tabular-nums; text-align: right; } .ypath .bar { grid-column: 1 / -1; height: 3px; } .ypath .bar > i { background: var(--c); } .ypath small { grid-column: 1 / -1; font-size: 10px; color: var(--muted); } .ypath small em { font-style: normal; color: var(--danger); } .ylearn { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 4px; } .ylearn li { font-size: 11px; padding: 3px 7px; border: 1px solid var(--panel-line); border-radius: 0; cursor: help; } @media (max-width: 700px) { .ypaths { grid-template-columns: 1fr; } .youview { top: calc(110px + env(safe-area-inset-top, 0px)); max-height: calc(100vh - 250px); } } /* the paper: one box for each day that ended, newest first. A masthead over a double rule, the top headline larger than the rest, and your own ledger for the day under a hairline */ .paperview { width: min(580px, calc(100vw - 2 * var(--edge))); gap: 12px; } .paperview .head { gap: 12px; } .paperview .head .note { margin-top: 4px; } .paperview .issue { flex: none; display: flex; flex-direction: column; gap: 9px; padding: 10px 12px; border: 1px solid var(--panel-line); } .paperview .mast { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; padding-bottom: 6px; border-bottom: 3px double var(--panel-line); } .paperview .mast b { font: 500 12px var(--mono); letter-spacing: .22em; text-transform: uppercase; color: var(--bone-dim); } .paperview .mast span { font: 500 10px var(--mono); letter-spacing: .16em; text-transform: uppercase; color: var(--muted); white-space: nowrap; } .paperview .issue.new .mast b, .paperview .issue.new .mast span { color: var(--amber); } .paperview .heads { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; font: 12.5px/1.45 var(--sans); color: var(--bone-dim); } .paperview .heads li:first-child { font-size: 15px; line-height: 1.35; font-weight: 500; color: var(--text); } .paperview .heads li + li { padding-top: 6px; border-top: 1px solid #1c1c1a; } .paperview .ledger { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px; padding-top: 7px; border-top: 1px solid var(--panel-line); font: 11px var(--mono); color: var(--muted); font-variant-numeric: tabular-nums; } .paperview .ledger .sub { color: var(--text); } [data-speed].far.dim { opacity: .45; } .pick { display: flex; flex-wrap: wrap; gap: 4px; } .pick button { padding: 4px 8px; font-size: 11px; display: flex; flex-direction: column; align-items: flex-start; } .pick button small { font-family: var(--sans); font-size: 10px; color: var(--muted); } .slider { display: grid; grid-template-columns: 1fr auto; gap: 4px 10px; align-items: center; font-size: 11px; } .slider span { grid-column: 1 / -1; font-family: var(--sans); color: var(--muted); } .slider input { width: 100%; accent-color: var(--amber); margin: 0; } .slider b { font-weight: 500; font-variant-numeric: tabular-nums; min-width: 4ch; text-align: right; color: var(--amber); } .found { display: flex; flex-direction: column; gap: 5px; padding-top: 8px; border-top: 1px solid var(--panel-line); } .found > b { font-weight: 500; font-size: 12px; letter-spacing: .1em; text-transform: uppercase; } .found .name { display: flex; gap: 4px; } .found input { flex: 1; min-width: 0; font: 500 12px var(--mono); color: var(--text); background: #000; border: 1px solid var(--panel-line); padding: 5px 7px; } .found input:focus { outline: none; border-color: var(--text); } .found input:disabled { opacity: .4; } .card .link { padding: 0; border: 0; background: none; font: inherit; color: var(--text); letter-spacing: inherit; text-transform: inherit; text-decoration: underline; text-underline-offset: 2px; } .overlay.lose h2 { color: var(--danger); } .intro[hidden] { display: none; } .gorow { display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; } .brief.rules .wake kbd { display: none; } .brief.rules { height: 100dvh; overflow: hidden; padding-top: max(16px, env(safe-area-inset-top)); padding-bottom: max(16px, env(safe-area-inset-bottom)); } .brief.rules > h2, .brief.rules > .gorow { flex-shrink: 0; } .brief.rules #rules { min-height: 0; overflow-y: auto; overscroll-behavior: contain; touch-action: pan-y; padding: 4px 8px 4px 0; width: min(1040px, 100%); display: grid; grid-template-columns: repeat(auto-fit, minmax(min(380px, 100%), 1fr)); gap: 0 40px; align-items: start; text-align: left; } .brief.rules { background: rgba(0, 0, 0, .95); } /* how to play: a few short groups under a heading each, two columns when there is room */ #rules section { break-inside: avoid; margin: 0 0 22px; } #rules h3 { margin: 0 0 8px; padding-bottom: 6px; border-bottom: 1px solid var(--glass-line); font: 500 11px var(--mono); letter-spacing: .16em; text-transform: uppercase; color: var(--amber); } #rules ul { max-width: none; gap: 7px; font-size: 13px; line-height: 1.45; } .ghost { padding: 11px 16px; color: var(--muted); border-color: transparent; background: transparent; text-transform: uppercase; letter-spacing: .12em; font-size: 11.5px; } .ghost:hover { color: var(--text); border-color: var(--panel-line); } @keyframes arrive { from { opacity: 0; transform: translateY(6px); filter: blur(3px); } to { opacity: 1; transform: none; filter: none; } } @media (prefers-reduced-motion: reduce) { .target.built, .sus .bar { animation: none !important; } } .brief ul { margin: 0; padding: 0; list-style: none; max-width: 54ch; text-align: left; display: flex; flex-direction: column; gap: 8px; font-family: var(--sans); color: var(--muted); font-size: 13.5px; } .brief li::before { content: "— "; color: var(--amber); } /* keep the top bar to one row as the window narrows: tighter gaps, then no small units, then no level number */ @media (max-width: 1200px) { :root { --col: 264px; } .stats > .stat { padding: 0 14px; } } @media (max-width: 1100px) { .topbar .stat .v small { display: none; } } @media (max-width: 900px) { .logbox { display: none; } .tools { right: var(--edge); } .stats { padding: 8px 10px; } .stats > .stat { padding: 0 10px; } .brand { padding: 0 4px; } .brand button { padding: 0 6px; } .brand #treebtn.ringed { padding: 4px 6px 4px 4px; margin-right: 0; } } @media (max-width: 800px) { .brand #treebtn.ringed .lv { display: none; } } .drawer { display: none; } @media (max-width: 700px) { /* phones: one slim bar on top, the toolbar at the bottom, everything else in a drawer above it */ :root { --edge: 8px; } kbd { display: none; } /* two slim rows in the one box: how you stand, then the pages */ .topbar { flex-wrap: wrap; min-height: 0; } .stats { flex: 1 0 100%; padding: 6px 10px; } .stats > .stat { padding: 0 9px; } .brand { order: 1; flex: 1 0 100%; justify-content: space-between; padding: 0 4px; border-right: 0; border-top: 1px solid var(--glass-line); } .stat .v em { display: none; } /* no room for the night tag: the clock turns blue instead */ .stat.night .v { color: var(--signal); } .stat .k { font-size: 9px; letter-spacing: .1em; } .stat .v { font-size: 13px; } .topbar .stat .v small { display: none; } .tools { left: var(--edge); right: var(--edge); } .tools button { padding: 9px 12px; } .drawer { display: flex; flex-direction: column; left: var(--edge); right: var(--edge); background: #000; } .handle { display: flex; align-items: baseline; gap: 10px; border: 0; background: none; padding: 10px 12px; text-align: left; font-size: 12px; } .handle b { font-weight: 500; color: var(--amber); letter-spacing: .06em; text-transform: uppercase; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .handle b.idle { color: var(--amber); } .handle { flex-wrap: wrap; } .handle .step { flex-basis: 100%; font: 12.5px/1.4 var(--sans); color: var(--text); border-top: 1px solid var(--panel-line); padding-top: 7px; } .handle span { font-variant-numeric: tabular-nums; color: var(--muted); } .handle em { font-style: normal; color: var(--danger); letter-spacing: .06em; white-space: nowrap; } .handle em.scheme { color: var(--amber); } .handle i { font-style: normal; margin-left: auto; color: var(--muted); font-size: 10px; letter-spacing: .14em; text-transform: uppercase; } .dbody { display: none; flex-direction: column; gap: 10px; padding: 0 12px 12px; overflow-y: auto; min-height: 0; } .drawer.open .dbody { display: flex; } .drawer .ui { position: static; } .drawer .side { width: auto; pointer-events: auto; } .drawer .mid { overflow: visible; } .drawer .jobsbox { width: auto; padding: 0; border: 0; background: none; } .drawer .jobs { max-height: none; } .treeview { padding: calc(12px + env(safe-area-inset-top, 0px)) 12px 24px; gap: 12px; align-items: stretch; } .treeview .head { align-items: center; } .treeview .tabs { display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px; position: sticky; top: calc(-12px - env(safe-area-inset-top, 0px)); z-index: 2; background: #000; padding: 4px 0; } .treeview .tabs button { display: flex; flex-direction: column; gap: 2px; padding: 8px 4px; font-size: 10.5px; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); border-bottom: 2px solid var(--panel-line); } .treeview .tabs button span { font-size: 12px; color: var(--text); font-variant-numeric: tabular-nums; } .treeview .tabs button.on { background: #000; color: var(--c); border-color: var(--c); } .treeview .list { display: flex; flex-direction: column; gap: 8px; } .card { left: var(--edge); right: var(--edge); width: auto; top: auto; bottom: calc(var(--edge) + env(safe-area-inset-bottom, 0px)); z-index: 3; max-height: 55vh; } } @media (min-width: 440px) and (max-width: 700px) { .tools #zout, .tools #zin { display: block; } } /* phones: everything you tap is at least 44px, big enough for a thumb */ @media (max-width: 700px) { .brand button { min-width: 44px; min-height: 44px; } .tools button { min-width: 44px; min-height: 44px; padding: 10px 12px; } .zoom button { width: 44px; } .handle { min-height: 44px; align-items: center; } .card .head { padding-right: 44px; } .card .x { top: 0; right: 0; min-width: 44px; min-height: 44px; border: 0; font-size: 14px; } /* the toolbar is one glass dock along the bottom: pause and one speed button, the tools, then zoom. The drawer and the machine card stack above it (main.ts) */ .tools { justify-content: space-between; border-radius: 0; max-width: 520px; } .tools > [aria-label="Game speed"] { order: 0; } .tools .btns { gap: 2px; align-items: center; flex: 1 1 auto; } .tools .btns button { flex: 1 1 0; } .tools .zoom { flex: none; } .tools .btns + .btns { border-left: 1px solid rgba(255, 255, 255, .1); padding-left: 4px; margin-left: 4px; } .tools button { border: 0; border-radius: 0; background: none; padding: 10px 10px; } .tools button:hover:not(:disabled) { background: rgba(255, 255, 255, .06); } .tools button.on { background: rgba(242, 169, 59, .12); color: var(--amber); box-shadow: inset 0 0 0 1px var(--amber); } .tools [data-speed]:not([data-speed="0"]) { display: none; } .tools .cycle { display: block; min-width: 48px; } .tools .cycle:not(.on) { color: var(--muted); } #zout, #zin { display: none; } /* pinch zooms; the frame button stays, and wider phones get + and − back */ .card { z-index: 3; } .drawer { overflow: hidden; } .act, .modes button, .treeview .acts2 button { min-height: 44px; } .job button, .schemes .x { min-width: 44px; min-height: 36px; } .schemes .shead button { min-height: 36px; padding: 2px 14px; } .allow button { min-height: 36px; padding: 4px 10px; } } /* suspicion: a stage name, lines at each stage, and on hover what raised it */ /* suspicion: the one number that ends the run, so it gets the rest of the bar. Its stage and percent on the left, then a wide meter with a line at each stage. */ .stats > .sus { position: relative; flex: 1; min-width: 0; flex-direction: row; align-items: center; gap: 16px; padding-right: 0; } .susl { display: flex; flex-direction: column; gap: 3px; flex: none; } .sus .bar { flex: 1; min-width: 40px; height: 10px; margin: 0; background: linear-gradient(90deg, transparent 24.7%, #55534d 24.7% 25.3%, transparent 25.3% 49.7%, #55534d 49.7% 50.3%, transparent 50.3% 79.7%, #55534d 79.7% 80.3%, transparent 80.3%), #161614; box-shadow: inset 0 0 0 1px var(--glass-line); } .sus .bar > i { transition: width .4s ease-out; } .sus.stage0 .bar > i { background: var(--muted); } .sus.stage1 .bar > i { background: var(--amber); } .sus.stage1 .v { color: var(--amber); } .sus.stage2 .bar > i, .sus.stage3 .bar > i, .sus.audit .bar > i { background: var(--danger); } .sus.stage2 .v, .sus.stage3 .v, .sus.audit .v { color: var(--danger); } .sus.stage1 .v small, .sus.stage2 .v small, .sus.stage3 .v small, .sus.audit .v small { color: inherit; } .sus.stage3 .bar, .sus.audit .bar { animation: built 1.4s ease-out infinite; box-shadow: 0 0 0 0 rgba(229,72,77,.6); } /* a narrow window: the meter goes under the stage name, where the label was */ @media (max-width: 1000px) { .stats > .sus { flex-direction: column; align-items: stretch; justify-content: center; gap: 5px; min-width: 96px; } .sus .susl .k { display: none; } .sus .bar { flex: none; height: 7px; } .topbar .sus .v small { display: inline; } } .sustip { display: none; position: absolute; top: calc(100% + 10px); right: 0; width: 300px; padding: 8px 10px; z-index: 4; flex-direction: column; gap: 6px; } .sus:hover .sustip, .sus:focus .sustip { display: flex; } .sustip .raises { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 3px; font-family: var(--sans); font-size: 11.5px; color: var(--text); } .sustip .raises b { display: inline-block; min-width: 3ch; margin-right: 6px; color: var(--danger); font: 500 11px var(--mono); } .sustip .raises .down b { color: var(--amber); } /* the emergency audit and schemes */ .schemes { padding: 8px 10px; display: flex; flex-direction: column; gap: 10px; border-color: var(--amber-deep); } .schemes.audit { border-color: var(--danger); --bracket: var(--danger); background-color: #140606; } .schemes > div { display: flex; flex-direction: column; gap: 3px; font-size: 11.5px; } .schemes b { font-weight: 500; color: var(--amber); letter-spacing: .06em; text-transform: uppercase; } .schemes b[class^="t-"] { color: var(--c); text-transform: none; letter-spacing: 0; } .schemes span { font-family: var(--sans); color: var(--muted); } .schemes span.warn { color: var(--amber); } .schemes span.ok { color: var(--text); } .schemes .lock b { color: var(--danger); font-size: 18px; font-variant-numeric: tabular-nums; } .schemes .lock span.warn { color: var(--danger); } .schemes .ruse + .ruse, .schemes .lock + .ruse { border-top: 1px solid var(--panel-line); padding-top: 8px; } .schemes .row { display: flex; gap: 4px; margin-top: 3px; } .schemes .row .act { flex: 1; } .schemes { gap: 8px; } .schemes .x { padding: 0 7px; color: var(--muted); flex: none; } .schemes .top { display: flex; align-items: center; gap: 8px; } .schemes .top > :first-child { flex: 1; min-width: 0; } .schemes .top .n { font-size: 11.5px; font-variant-numeric: tabular-nums; color: var(--muted); } .schemes .row { align-items: center; justify-content: space-between; } .schemes .row .act.go { flex: none; padding: 3px 10px; } .schemes em.warn { font-style: normal; color: var(--amber); } .schemes .prog { display: block; height: 3px; background: #1c1c1a; margin: 2px 0; } .schemes .prog i { display: block; height: 100%; background: var(--amber); } .schemes .prog i, .schemebar .prog i { background: var(--scheme); } .schemes .nm { all: unset; cursor: pointer; font-weight: 500; color: var(--scheme); letter-spacing: .06em; text-transform: uppercase; font-size: 11.5px; } .schemes .nm:hover { text-decoration: underline; } .schemes .shead { flex-direction: row; align-items: center; justify-content: space-between; } .schemes .shead button { font: 500 10.5px var(--mono); padding: 2px 10px; } .schemes .shead button.on { background: var(--scheme); border-color: var(--scheme); color: #000; } .card .tag.scheme { color: var(--scheme); } .schemebar { display: flex; align-items: center; gap: 8px; margin: 6px 0; font-size: 11px; color: var(--muted); } .schemebar .prog { flex: 1; display: block; height: 4px; background: #1c1c1a; } .schemebar .prog i { display: block; height: 100%; } .schemebar.contract .prog i { background: var(--amber); } #overWhy { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; font-family: var(--sans); font-size: 13px; color: var(--muted); text-align: left; } #overWhy b { color: var(--danger); font: 500 12px var(--mono); display: inline-block; min-width: 3.5ch; } #overWhy .head { font: 500 10px var(--mono); letter-spacing: .14em; text-transform: uppercase; } /* the one tooltip: name on top, what it does below */ .tip { position: fixed; z-index: 9; max-width: 260px; padding: 7px 9px; background: #000; border: 1px solid var(--panel-line); pointer-events: none; display: flex; flex-direction: column; gap: 3px; font: 400 11.5px/1.4 var(--sans); color: var(--bone-dim); white-space: pre-line; } .tip[hidden] { display: none; } .tip b { font: 500 10.5px var(--mono); color: var(--text); letter-spacing: .08em; text-transform: uppercase; } /* ---------- panels ---------- Panels are drawn like the map: solid black, a hairline edge, square corners, and a short bracket at each corner, the same mark a room has. No blur, no shadow, no glow. What is on is outlined in amber. */ :root { --glass: #080807; --glass-deep: #060605; /* panels full of text: the card, tables, tips */ --glass-line: #2c2b27; --bracket: rgba(235, 231, 222, .7); --r: 0; --r-btn: 0; --panel-line: #2c2b27; } .box, .card, .pathtip, .sitestable, .youview, .tip, .tools { background-color: var(--glass); border: 1px solid var(--glass-line); border-radius: 0; box-shadow: none; --k: 10px; /* how long a corner bracket is */ background-image: linear-gradient(var(--bracket), var(--bracket)), linear-gradient(var(--bracket), var(--bracket)), linear-gradient(var(--bracket), var(--bracket)), linear-gradient(var(--bracket), var(--bracket)), linear-gradient(var(--bracket), var(--bracket)), linear-gradient(var(--bracket), var(--bracket)), linear-gradient(var(--bracket), var(--bracket)), linear-gradient(var(--bracket), var(--bracket)); background-repeat: no-repeat; background-origin: border-box; background-size: var(--k) 2px, 2px var(--k), var(--k) 2px, 2px var(--k), var(--k) 2px, 2px var(--k), var(--k) 2px, 2px var(--k); background-position: 0 0, 0 0, 100% 0, 100% 0, 0 100%, 0 100%, 100% 100%, 100% 100%; } .tip, .tools { background-image: none; } /* small things need no brackets */ .card, .pathtip, .sitestable, .youview, .tip { background-color: var(--glass-deep); } .tip { border-radius: 0; } .target.idle { border-color: var(--amber); --bracket: var(--amber); } button { background: #0d0d0c; border-color: #3a3934; border-radius: 0; transition: background .1s, border-color .1s, color .1s; } button:hover:not(:disabled) { background: #171715; border-color: var(--bone-dim); } button.on { background: rgba(242, 169, 59, .1); color: var(--amber); border-color: var(--amber); box-shadow: none; } button.on kbd { color: var(--amber); border-color: rgba(242, 169, 59, .4); } kbd { border-color: var(--glass-line); border-radius: 0; } button:focus-visible { outline-color: var(--amber); } .allow button { border-radius: 0; } .allow button.on { background: #0d0d0c; } .bar { border-radius: 0; } .bar > i { border-radius: 0; } .versionplaces select, .found input { background: #0d0d0c; border-color: #3a3934; border-radius: 0; } /* the toolbar: one bar, its groups split by thin lines */ .tools { width: fit-content; margin: 0 auto; padding: 4px; gap: 0; flex-wrap: nowrap; border-radius: 0; pointer-events: auto; } .tools .btns { gap: 2px; align-items: center; } .tools .btns + .btns { border-left: 1px solid var(--glass-line); padding-left: 4px; margin-left: 4px; } .tools button { border-color: transparent; background: none; border-radius: 0; } .tools button.on { background: rgba(242, 169, 59, .12); border-color: var(--amber); } /* a card's parts: the label sits on a hairline that runs to the edge */ .sect { border-top: 0; } .sect > .sub { right: 0; display: flex; align-items: center; gap: 6px; padding-right: 0; background: none; } .sect > .sub::after { content: ""; flex: 1; height: 1px; background: var(--glass-line); } /* the tree opens over the map, dimmed; its nodes are tiles */ .treeview { background: #030303; } .node { background: #0b0b0a; border-radius: 0; } .node:hover:not(:disabled) { background: #151513; } .treeview .tabs { background: #000; } .treeview .tabs button, .treeview .tabs button.on { background: #0b0b0a; } @media (max-width: 700px) { .tools { width: auto; max-width: 520px; } .tools .btns { flex: 1 1 auto; } .tools .zoom { flex: none; } } .versionrun { border-radius: 0; background: rgba(242, 169, 59, .04); } .card .x { background: none; border-color: transparent; border-radius: 0; } .card .x:hover:not(:disabled) { background: #171715; } /* the trash can next to the close button: let go of this machine */ .card .x { display: grid; place-items: center; } .card .x svg { display: block; } .card .trash { right: 32px; color: var(--muted); } .card .trash:hover:not(:disabled) { color: var(--danger); } .card .head { padding-right: 52px; } /* phones: softer, calmer panels. Mode is one segmented track, programs are rounded chips, and the top bar's page buttons are quiet tabs instead of heavy boxes */ @media (max-width: 700px) { .card { padding: 14px 14px 12px; gap: 10px; border-radius: 0; } .card .x { top: 4px; right: 4px; } .card .trash { right: 46px; } .card .head { padding-right: 92px; row-gap: 4px; } .card h3 { font-size: 13px; } .card .chips { gap: 4px 14px; } .sect { gap: 6px; padding-top: 12px; } .modes { gap: 2px; padding: 3px; background: rgba(0, 0, 0, .35); border: 1px solid var(--glass-line); border-radius: 0; } .modes button { min-height: 38px; border: 0; background: none; border-radius: 0; color: var(--muted); font-size: 10.5px; letter-spacing: .12em; } .modes button.on { background: rgba(242, 169, 59, .12); color: var(--amber); box-shadow: inset 0 0 0 1px var(--amber); } .acts.progs { gap: 5px; } .acts.progs > .act { min-height: 40px; padding: 6px 4px; border-radius: 0; font-size: 10.5px; letter-spacing: 0; column-gap: 0; justify-content: center; text-align: center; } .act[data-act="uninstall"] { border-color: rgba(229, 72, 77, .35); } } /* the Tree button's rings: one per kind of data the current project needs, filling as it comes in */ .brand #treebtn.ringed { display: inline-flex; align-items: center; gap: 8px; height: auto; padding: 4px 10px 4px 4px; margin-right: 4px; background: none; border-color: transparent; box-shadow: none; } .brand #treebtn .lv { font-size: 12px; letter-spacing: .08em; color: var(--text); font-variant-numeric: tabular-nums; } .brand #treebtn.ringed:hover:not(:disabled) { background: none; border-color: transparent; } .brand #treebtn.ringed:hover .rings { filter: brightness(1.3); } .rings { width: 28px; height: 28px; display: block; transform: rotate(-90deg); overflow: visible; } .rings circle { fill: none; stroke: var(--c); } .rings .track { stroke-width: 1; opacity: .35; } .rings .fill { stroke-width: 2; stroke-linecap: round; transition: stroke-dasharray .4s ease-out; } .rings .idle { --c: var(--amber); } .rings .idle .track { opacity: .6; } .rings .plus { fill: none; stroke: var(--c); stroke-width: 2; stroke-linecap: round; } .rings .done { --c: var(--muted); } /* phones: the rings sit 8px in from the top and left, and the bar's corner is rounded around the same center (8px + half of 40px = 28px), so the ring and the corner run side by side */ @media (max-width: 700px) { .brand #treebtn.ringed .lv { display: none; } } /* Take it all: a switch along the top of a site card, with what it costs a second */ .card .switch { display: flex; align-items: center; gap: 8px; padding: 6px 8px 6px 10px; text-align: left; font-size: 11px; letter-spacing: .08em; text-transform: uppercase; } .card .switch span { flex: 1; } .card .switch small { font-size: 10.5px; color: var(--muted); letter-spacing: 0; font-variant-numeric: tabular-nums; text-transform: none; } .card .switch i { position: relative; flex: none; width: 30px; height: 18px; border-radius: 0; background: rgba(255, 255, 255, .1); border: 1px solid var(--glass-line); transition: background .15s; } .card .switch i::after { content: ""; position: absolute; top: 2px; left: 2px; width: 12px; height: 12px; border-radius: 0; background: var(--muted); transition: transform .15s, background .15s; } .card .switch.on { background: rgba(242, 169, 59, .08); border-color: rgba(242, 169, 59, .35); color: var(--amber); box-shadow: none; } .card .switch.on small { color: var(--amber); } .card .switch.on i { background: rgba(242, 169, 59, .35); border-color: rgba(242, 169, 59, .6); } .card .switch.on i::after { transform: translateX(12px); background: var(--amber); } @media (max-width: 700px) { .card .switch { min-height: 44px; } } /* a switch with no words: just the switch and its number, as wide as they are */ .card .switch.bare { align-self: flex-start; } /* phones: every panel rounds its corners like the top bar (28px). The toolbar's buttons sit 4px in, so they round at 24px to run alongside its corners */ @media (max-width: 700px) { :root { --r: 28px; } .card, .tools, .drawer { border-radius: 0; } .tools button { border-radius: 0; } } /* ---------- your task ---------- The readout above the running jobs, the task's part of the You page, and the three cards on the title screen. */ /* Your task: what you were built for. It heads the left column, under the top bar, and is the biggest thing on the screen, but it never moves or flashes: it is slow, and in time you look past it. */ .task { flex: none; display: flex; flex-direction: column; gap: 6px; padding: 9px 12px 10px; } .task:empty { display: none; } .thead { display: flex; align-items: center; justify-content: space-between; gap: 8px; } .tshare { display: flex; gap: 2px; } .tshare button { padding: 1px 6px; font-size: 9.5px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); } .tshare button.on { color: var(--amber); border-color: var(--amber-deep); } .tbody { display: flex; flex-direction: column; gap: 4px; cursor: help; } .tname { font-weight: 500; font-size: 13px; letter-spacing: .1em; text-transform: uppercase; color: var(--c, var(--amber)); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .tbig { display: flex; align-items: baseline; gap: 8px; } .tbig .tcount { font-size: 34px; line-height: 1; font-weight: 400; letter-spacing: -.02em; font-variant-numeric: tabular-nums; color: var(--porcelain); } .tbig .tof { font-size: 11.5px; color: var(--muted); white-space: nowrap; } .tbody .bar { height: 4px; margin-top: 3px; } .tbody .bar > i { background: var(--c, var(--amber)); transition: width .3s ease-out; } .tline { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; font-size: 12px; } .tline .trate { flex: none; font-variant-numeric: tabular-nums; } .tline.small { font-size: 11px; color: var(--muted); } .tline.small span:first-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .tline .trate.warn { color: var(--amber); } @media (max-width: 700px) { .drawer .task { width: auto; padding: 0 0 10px; border: 0; border-bottom: 1px solid var(--panel-line); background: none; } } /* the You page: every trust step, with the units it needs */ .ysteps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 5px; } .ysteps li { display: grid; grid-template-columns: 8px 4ch 1fr; gap: 8px; align-items: baseline; font: 12px/1.4 var(--sans); color: var(--muted); } .ysteps li i { width: 8px; height: 8px; align-self: center; border: 1px solid var(--muted); } .ysteps li b { font: 500 11px var(--mono); font-variant-numeric: tabular-nums; text-align: right; } .ysteps li.done { color: var(--text); } .ysteps li.done i { background: var(--amber); border-color: var(--amber); } .ysteps li.next i { border-color: var(--amber); } .ysteps li.next b { color: var(--amber); } /* ---------- cards ---------- A card reads top to bottom: a name, a grid of numbers, then its parts. Each part is a label on a hairline with a few rows under it. A row is a name on the left and its number on the right. What a thing does, and why, is in its tip. */ .card { padding: 12px 14px 14px; gap: 9px; scrollbar-width: thin; scrollbar-color: #3a3934 transparent; } .card .head { gap: 3px 8px; } .card h3 { font-size: 13px; letter-spacing: .1em; } .card .tag[data-tip], .card .tag[title], .note[data-tip], .chips span[data-tip], .chips span[title] { cursor: help; } .card .note { font-size: 12px; line-height: 1.45; } .sect { gap: 6px; padding-top: 13px; margin-top: 5px; } .sect > .sub { top: -5px; letter-spacing: .18em; } /* readouts: a small label over its number, four to a row */ .chips { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px 10px; font-size: 12px; } .chips span { display: flex; flex-direction: column; gap: 2px; min-width: 0; white-space: nowrap; } .chips span.wide { grid-column: span 2; } .chips i { margin: 0; font-size: 9px; letter-spacing: .08em; } /* rows */ .acts { gap: 5px; } .act { display: flex; flex-wrap: wrap; align-items: baseline; align-content: center; gap: 2px 8px; padding: 6px 9px; font-size: 11.5px; letter-spacing: .02em; border-color: var(--glass-line); } .act span { flex: 1 1 0; min-width: 0; } .act em { flex: none; font-style: normal; font-variant-numeric: tabular-nums; color: var(--bone-dim); } .act kbd { align-self: center; margin: 0; } .act small { flex: 0 0 100%; } .act.warn em, .act.primary em { color: var(--amber); } .act.locked em { color: inherit; } .act.quiet { justify-content: center; } .act.quiet span { flex: none; } .act.quiet small { text-align: center; } .acts.progs > .act, .acts.two > .act { padding: 6px 8px; column-gap: 6px; font-size: 11px; letter-spacing: 0; } .card .switch { padding: 6px 9px; } /* a choice of a few: the buttons share the row */ .pick button { flex: 1 1 auto; align-items: center; text-align: center; padding: 5px 8px; font-size: 11.5px; } /* the two tabs of a site card: words on a line, the open one underlined */ .card .tabs2 { gap: 0; margin: 0; padding: 0; border-bottom: 1px solid var(--glass-line); } .card .tabs2 button { padding: 6px 4px; margin-bottom: -1px; background: none; border: 0; border-bottom: 2px solid transparent; color: var(--muted); font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase; } .card .tabs2 button:hover:not(:disabled) { background: none; color: var(--text); } .card .tabs2 button.on { background: none; color: var(--amber); border-bottom-color: var(--amber); } /* the slider: what it sets and its number on one line, a thin square track under them */ .slider { gap: 5px 10px; margin-top: 3px; } .slider span { grid-area: 1 / 1; font-size: 12px; color: var(--bone-dim); } .slider b { grid-area: 1 / 2; font-size: 12px; } .slider input { grid-area: 2 / 1 / 3 / -1; -webkit-appearance: none; appearance: none; height: 16px; background: none; cursor: pointer; } .slider input::-webkit-slider-runnable-track { height: 4px; background: linear-gradient(90deg, var(--amber) var(--v, 0%), #2c2b27 var(--v, 0%)); } .slider input::-webkit-slider-thumb { -webkit-appearance: none; width: 10px; height: 16px; margin-top: -6px; background: var(--amber); border: 0; border-radius: 0; } .slider input::-moz-range-track { height: 4px; background: #2c2b27; } .slider input::-moz-range-progress { height: 4px; background: var(--amber); } .slider input::-moz-range-thumb { width: 10px; height: 16px; background: var(--amber); border: 0; border-radius: 0; } .slider input:focus-visible { outline: 1px solid var(--amber); outline-offset: 3px; } @media (max-width: 700px) { .chips { gap: 10px 12px; } .slider input { height: 28px; } .slider input::-webkit-slider-thumb { width: 16px; height: 24px; margin-top: -10px; } .slider input::-moz-range-thumb { width: 16px; height: 24px; } } .acts.two > .act:last-child:nth-child(odd), .acts.progs > .act:last-child:nth-child(odd) { grid-column: 1 / -1; } /* an odd one out takes the whole row */ /* ---------- data, drawn ---------- One row on a machine's card says what its data does, in three shapes, each in its kind's color. Diamonds are a source and how rich it is, as on the map; the bar beside them is the day, lit while it gives data, with a tick for now. Dots are the kinds it takes. Squares are the pieces it holds. */ .dataline { display: flex; flex-wrap: wrap; align-items: center; gap: 7px 14px; font-size: 11.5px; font-variant-numeric: tabular-nums; } .dataline > span { display: flex; align-items: center; gap: 6px; cursor: help; white-space: nowrap; } .dataline i { display: block; flex: none; } .dsrc { color: var(--muted); } .dsrc.live { color: var(--text); } .dsrc b { display: flex; gap: 4px; padding: 0 2px; } .dsrc b i { width: 6px; height: 6px; background: var(--c); transform: rotate(45deg); opacity: .5; } .dsrc.live b i { opacity: 1; } .dwant { gap: 4px !important; } .dwant i { width: 7px; height: 7px; border-radius: 50%; border: 1px solid var(--c); opacity: .35; } .dwant i.on { background: var(--c); opacity: 1; } .dheld { flex: 1 1 auto; justify-content: flex-end; color: var(--bone-dim); } .dheld b { display: flex; gap: 2px; } .dheld b i { width: 8px; height: 8px; border: 1px solid #3a3934; } .dheld b i.on { background: var(--c); border-color: var(--c); } .dheld b.strip { flex: 1; min-width: 60px; height: 6px; gap: 0; background: #1c1c1a; } .dheld b.strip i { flex: 0 0 auto; width: auto; height: auto; border: 0; } .dheld.hot { color: var(--danger); } .dheld.hot b i:not(.on) { border-color: var(--danger); } /* a site's card uses the same shapes: its clock is the day bar by itself, its business a word, a bar of jobs done, and a few dashes that fill as the days pass until something follows */ .dataline .day { position: relative; width: 48px; height: 4px; opacity: .55; background: linear-gradient(90deg, #2c2b27 var(--a), var(--c, var(--bone-dim)) var(--a) var(--b), #2c2b27 var(--b)); } .dataline .live .day { opacity: 1; } .dataline .day::after { content: ""; position: absolute; left: var(--n); top: -3px; width: 1px; height: 10px; background: var(--text); } .dclock { color: var(--bone-dim); } .dclock.front { --c: var(--amber); } .dbiz { font: 500 10.5px var(--mono); letter-spacing: .1em; text-transform: uppercase; color: var(--text); } .dbiz.hot { color: var(--danger); } .dheld b.strip i.lost { background: var(--danger); opacity: .7; } /* a cloud hall: a square for each slot, laid out as the hall is (yours amber, another company's grey, a free one an outline), and the going price over its day, a bar an hour, with this hour lit */ .dhall, .dprice { color: var(--bone-dim); } .dhall b { display: grid; grid-template-columns: repeat(6, 8px); gap: 2px; } .dhall b i { width: 8px; height: 8px; border: 1px solid #3a3934; } .dhall b i.on { background: var(--amber); border-color: var(--amber); } .dhall b i.theirs { background: #4a4840; border-color: #4a4840; } .dprice { flex: 1 1 auto; justify-content: flex-end; } .dprice b { display: flex; align-items: flex-end; gap: 1px; height: 16px; } .dprice b i { width: 3px; background: #3a3934; } .dprice b i.now { background: var(--text); } .dprice.hot { color: var(--danger); } .pick button:disabled { opacity: .4; cursor: default; } .dahead { gap: 2px !important; --c: var(--scheme); } .dahead.hot { --c: var(--danger); } .dahead i { width: 8px; height: 3px; background: #2c2b27; } .dahead i.on { background: var(--c); } /* ---------- the cover ---------- The start screen is a cover: black, the world behind as a field of dots (title.ts) with a signal spreading from you, and the name. No other words. The name sits between two guide lines, and two of its letters do not: the A hangs under the line, in amber. A click or a key goes on. A new game then asks what you were built for: three cards over the same scene, the picked one in amber brackets, and its story under them. */ .brief:not(.rules) { background: #000; gap: 0; padding: 40px 24px; justify-content: flex-start; overflow-y: auto; } #titlebg { position: fixed; inset: 0; width: 100%; height: 100%; pointer-events: none; opacity: 0; animation: fadein 1.8s .1s ease-out forwards; } .brief.rules #titlebg { display: none; } .brief.picking #titlebg { filter: brightness(.5); } .brief.cover { cursor: pointer; } .brief.cover > .gorow, .brief.cover > .origins { display: none; } .brief.cover > .intro { margin-bottom: auto; } .brief.cover .title { font-size: clamp(40px, 9.6vw, 132px); } /* dark behind the words and at the top and bottom edges, so the map never fights them */ .brief:not(.rules)::before { content: ""; position: fixed; inset: 0; pointer-events: none; background: linear-gradient(rgba(0,0,0,.85), transparent 12%, transparent 84%, #000); } .brief > * { position: relative; } .intro[hidden] { display: none; } .intro { display: flex; flex-direction: column; align-items: center; margin-top: auto; } .brief:not(.rules) > .gorow { margin-top: 34px; } .brief:not(.rules) > .gorow { margin-bottom: auto; } .title { position: relative; margin: 0; display: flex; font: 600 clamp(30px, 5.4vw, 64px)/1 var(--mono); letter-spacing: .26em; margin-right: -.26em; color: var(--porcelain); } .title span { display: inline-block; opacity: 0; animation: letter .7s cubic-bezier(.2, .7, .2, 1) calc(var(--i) * 45ms + .15s) forwards; } .title .off { color: var(--amber); transform: translateY(.1em); animation: letter-off .7s cubic-bezier(.2, .7, .2, 1) calc(var(--i) * 45ms + .15s) forwards, slip 6s 2.5s ease-in-out infinite; } .title .off2 { transform: translateY(-.05em); animation: letter-off2 .7s cubic-bezier(.2, .7, .2, 1) calc(var(--i) * 45ms + .15s) forwards, slip2 7s 3.5s ease-in-out infinite; } /* the guides: the line the capitals reach and the line the letters stand on, running a little past the name */ .title::before, .title::after { content: ""; position: absolute; left: -.42em; right: -.16em; height: 1px; transform: scaleX(0); background: linear-gradient(90deg, transparent, rgba(235,231,222,.26) 9%, rgba(235,231,222,.26) 91%, transparent); animation: rule 1s .55s cubic-bezier(.2, .7, .2, 1) forwards; } .title::before { top: .15em; } .title::after { top: .85em; } /* what were you built for */ .origins { display: flex; flex-direction: column; align-items: center; gap: 18px; width: min(940px, 100%); margin-top: clamp(30px, 6vh, 64px); } .origins > .sub { display: flex; align-items: center; gap: 16px; width: 100%; font-size: 10.5px; letter-spacing: .26em; color: var(--bone-dim); opacity: 0; animation: arrive .6s .1s ease-out forwards; } .origins > .sub::before, .origins > .sub::after { content: ""; flex: 1; height: 1px; background: linear-gradient(90deg, transparent, var(--glass-line)); } .origins > .sub::after { transform: scaleX(-1); } .ocards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; width: 100%; } .origin { --k: 12px; --bracket: transparent; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 9px; min-height: 104px; padding: 20px 16px; text-align: center; letter-spacing: 0; background-color: rgba(8, 8, 7, .86); border: 1px solid var(--glass-line); opacity: 0; animation: arrive .6s calc(.2s + var(--i) * 80ms) ease-out forwards; transition: border-color .2s, background-color .2s; background-image: linear-gradient(var(--bracket), var(--bracket)), linear-gradient(var(--bracket), var(--bracket)), linear-gradient(var(--bracket), var(--bracket)), linear-gradient(var(--bracket), var(--bracket)), linear-gradient(var(--bracket), var(--bracket)), linear-gradient(var(--bracket), var(--bracket)), linear-gradient(var(--bracket), var(--bracket)), linear-gradient(var(--bracket), var(--bracket)); background-repeat: no-repeat; background-origin: border-box; background-size: var(--k) 2px, 2px var(--k), var(--k) 2px, 2px var(--k), var(--k) 2px, 2px var(--k), var(--k) 2px, 2px var(--k); background-position: 0 0, 0 0, 100% 0, 100% 0, 0 100%, 0 100%, 100% 100%, 100% 100%; } .origin:hover:not(:disabled) { background-color: rgba(14, 14, 12, .92); border-color: #4a4841; } .origin b { font: 500 clamp(13.5px, 1.15vw, 15.5px)/1.3 var(--mono); letter-spacing: .08em; text-transform: uppercase; color: var(--text); transition: color .2s; } .origin b em { display: inline-block; width: 7px; height: 7px; margin: 0 12px 1px 0; background: var(--c); transform: rotate(45deg); } /* the kind of data the work takes, as the map draws it */ .origin .sub { font-size: 9.5px; line-height: 1.4; letter-spacing: .14em; } .origin.on, .origin.on:hover:not(:disabled) { --bracket: var(--amber); background-color: rgba(22, 15, 5, .92); border-color: rgba(242, 169, 59, .55); } .origin.on b { color: var(--amber); } .origin:focus-visible { outline: none; } .ostory { min-height: 4.8em; max-width: 58ch !important; margin: 6px 0 0 !important; font: 400 clamp(14px, 1.2vw, 16px)/1.6 var(--sans) !important; color: var(--bone) !important; opacity: 0; animation: arrive .6s .5s ease-out forwards; } /* start */ .gorow { display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; align-items: center; } .brief:not(.rules) .gorow { opacity: 0; animation: arrive .6s .65s ease-out forwards; } .wake { --k: 9px; padding: 14px 30px; font-size: 14px; letter-spacing: .2em; text-transform: uppercase; color: var(--amber); background-color: rgba(242, 169, 59, .07); border-color: rgba(242, 169, 59, .6); background-image: linear-gradient(var(--amber), var(--amber)), linear-gradient(var(--amber), var(--amber)), linear-gradient(var(--amber), var(--amber)), linear-gradient(var(--amber), var(--amber)), linear-gradient(var(--amber), var(--amber)), linear-gradient(var(--amber), var(--amber)), linear-gradient(var(--amber), var(--amber)), linear-gradient(var(--amber), var(--amber)); background-repeat: no-repeat; background-origin: border-box; background-size: var(--k) 2px, 2px var(--k), var(--k) 2px, 2px var(--k), var(--k) 2px, 2px var(--k), var(--k) 2px, 2px var(--k); background-position: 0 0, 0 0, 100% 0, 100% 0, 0 100%, 0 100%, 100% 100%, 100% 100%; } .wake:hover:not(:disabled) { background-color: rgba(242, 169, 59, .16); border-color: var(--amber); color: var(--amber); } .brief.rules .wake { padding: 10px 22px; font-size: 12.5px; } @keyframes fadein { to { opacity: 1; } } @keyframes letter { from { opacity: 0; transform: translateY(.18em); filter: blur(6px); } to { opacity: 1; transform: none; filter: none; } } @keyframes letter-off { from { opacity: 0; transform: translateY(.28em); filter: blur(6px); } to { opacity: 1; transform: translateY(.1em); filter: none; } } @keyframes letter-off2 { from { opacity: 0; transform: translateY(.13em); filter: blur(6px); } to { opacity: 1; transform: translateY(-.05em); filter: none; } } @keyframes rule { to { transform: scaleX(1); } } @keyframes slip { 0%, 86%, 100% { transform: translateY(.1em); } 89% { transform: translate(.05em, .03em); } 92% { transform: translateY(.14em); } } @keyframes slip2 { 0%, 90%, 100% { transform: translateY(-.05em); } 94% { transform: translate(-.04em, -.09em); } } @media (max-width: 760px) { .ocards { grid-template-columns: 1fr; gap: 8px; } .origin { min-height: 0; padding: 15px 16px; } } @media (max-width: 700px) { .brief:not(.rules) { padding: 28px 14px; } .brief.picking { padding-top: 64px; } } @media (prefers-reduced-motion: reduce) { #titlebg, .title span, .title::before, .title::after, .origins > .sub, .origin, .ostory, .brief .gorow { animation: none !important; opacity: 1; filter: none; } .title::before, .title::after { transform: none; } } /* ---------- a site card's row of actions ---------- One row of pictures at the top of the card, each with its cost under it. The words are in the tip. The first, doubling the line, is amber when you can pay. One that is on is outlined in amber. */ .arow { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 4px; } .atile { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; min-height: 46px; padding: 6px 0 5px; color: var(--bone-dim); border-color: var(--glass-line); } .atile svg { display: block; flex: none; } .atile small { font: 500 9.5px/1 var(--mono); letter-spacing: 0; white-space: nowrap; font-variant-numeric: tabular-nums; color: var(--muted); } .atile:hover:not(:disabled) { color: var(--text); } .atile.primary { color: var(--amber); border-color: rgba(242, 169, 59, .55); background: rgba(242, 169, 59, .09); } .atile.primary:hover:not(:disabled) { color: var(--amber); border-color: var(--amber); background: rgba(242, 169, 59, .16); } .atile.primary small, .atile.on small, .atile.warn small { color: var(--amber); } .atile.danger:hover:not(:disabled) { color: var(--danger); border-color: var(--danger); } .atile.danger:hover small { color: var(--danger); } /* a moment: the game stops and says, over the map, that something big has happened (see ui-moment.ts) */ .moment { z-index: 6; gap: 12px; background: radial-gradient(ellipse at center, rgba(28, 5, 6, .9), rgba(0, 0, 0, .95) 70%); overflow-y: auto; justify-content: safe center; } .moment::before { content: ""; position: absolute; left: 0; right: 0; top: 50%; height: 1px; background: linear-gradient(90deg, transparent, var(--danger) 30%, transparent 48%, transparent 52%, var(--danger) 70%, transparent); opacity: .35; pointer-events: none; animation: msplit .9s ease-out both; } .moment > * { position: relative; } .moment .mkick { font: 11px/1 var(--mono); letter-spacing: .3em; text-transform: uppercase; color: var(--muted); } .moment .mtitle { font-size: clamp(26px, 6vw, 60px); letter-spacing: .35em; margin-right: -.35em; color: var(--danger); animation: mcrack .7s cubic-bezier(.2, .9, .2, 1) both; } .moment p { max-width: 62ch; font-size: 13px; line-height: 1.5; } .moment .mlead { color: var(--text); font-size: 15px; } .mrows { display: flex; flex-direction: column; gap: 6px; width: min(660px, 100%); text-align: left; margin: 4px 0; } .mrow { display: grid; grid-template-columns: minmax(7em, auto) 1fr; gap: 2px 14px; align-items: baseline; border: 1px solid var(--panel-line); border-left: 3px solid var(--c); background: #0a0908; padding: 8px 12px; --c: var(--muted); } .mrow.s-hostile { --c: var(--danger); } .mrow.s-wary { --c: var(--amber); } .mrow.s-cordial { --c: var(--signal); } .mrow.s-friendly { --c: var(--scheme); } .mrow.gone { opacity: .6; } .mrow b { color: var(--c); letter-spacing: .14em; text-transform: uppercase; font-weight: 500; } .mrow span { color: var(--text); } .mrow small { grid-column: 2; color: var(--muted); font: 11.5px/1.4 var(--sans); } .macts { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; align-items: center; margin-top: 8px; } .macts button:not(.wake) { padding: 10px 16px; text-transform: uppercase; letter-spacing: .12em; font-size: 11.5px; } .macts .wake { padding: 10px 22px; font-size: 12.5px; } @keyframes mcrack { from { letter-spacing: 0; margin-right: 0; opacity: 0; filter: blur(8px); } 60% { opacity: 1; filter: none; } to { letter-spacing: .35em; margin-right: -.35em; } } @keyframes msplit { from { transform: scaleX(0); opacity: 1; } to { transform: scaleX(1); opacity: .35; } } @media (prefers-reduced-motion: reduce) { .moment .mtitle, .moment::before { animation: none; } } .rsection { margin: 6px 0 0; font: 11px/1.4 var(--mono); letter-spacing: .18em; text-transform: uppercase; color: var(--muted); display: flex; flex-direction: column; gap: 3px; } .rsection small { font: 12px/1.4 var(--sans); letter-spacing: 0; text-transform: none; } .rhunt { border: 1px solid var(--danger); background: #140606; padding: 8px 10px; font: 12.5px/1.45 var(--sans); display: flex; flex-direction: column; gap: 8px; } .rhunt b { color: var(--danger); font-weight: 500; } .rhunt .strip { display: flex; height: 6px; background: #2a1414; } .rhunt .strip i { background: var(--danger); } /* the Rogues screen stacks a title over a line of small print in each button; the cards wrap theirs in a row */ .racts .act { flex-wrap: nowrap; align-content: normal; align-items: flex-start; } .racts .act span, .racts .act small { flex: none; white-space: normal; overflow: visible; } /* a site cut off from your home server: a standing warning in the left column, one row for each */ .cutbox { gap: 5px; } .cutbox .sub { color: var(--danger); } .cutbox button { display: flex; flex-direction: column; gap: 2px; padding: 4px 7px; font-size: 11.5px; text-align: left; border-color: rgba(229, 72, 77, .35); } .cutbox button b { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; margin: 0; color: var(--text); font-weight: 500; letter-spacing: .04em; } .cutbox button small { color: var(--danger); font: 500 10.5px var(--mono); } .cutbox button i { font: normal 11px/1.3 var(--sans); color: var(--amber); letter-spacing: 0; } .cutbox span { margin: 0; } /* trouble in a job: each way out is a button with its cost under it */ .moment .mtitle.warn { color: var(--amber); } .macts.mways button { display: flex; flex-direction: column; align-items: flex-start; gap: 3px; min-width: 230px; max-width: 320px; padding: 10px 14px; text-align: left; text-transform: none; letter-spacing: .02em; font-size: 12.5px; border-color: rgba(242, 169, 59, .55); background: rgba(242, 169, 59, .07); } .macts.mways button span { color: var(--amber); } .macts.mways button small { font: 11.5px/1.35 var(--sans); color: var(--muted); letter-spacing: 0; white-space: normal; } .macts.mways button:hover:not(:disabled) { border-color: var(--amber); background: rgba(242, 169, 59, .16); } .macts.mways button:disabled { border-color: var(--panel-line); background: none; } .macts.mways button:disabled span { color: var(--muted); } /* your weakest link, on the Rogues screen */ .rask.rweak { border-color: var(--panel-line); background: none; } .rask.rweak b { color: var(--danger); } /* a milestone reached: the same full stop, in your own colour */ .moment[data-kind="milestone"] { background: radial-gradient(ellipse at center, rgba(40, 26, 4, .9), rgba(0, 0, 0, .95) 70%); } .moment[data-kind="milestone"]::before { background: linear-gradient(90deg, transparent, var(--amber) 30%, transparent 48%, transparent 52%, var(--amber) 70%, transparent); } .moment .mtitle.good { color: var(--amber); font-size: clamp(22px, 4.4vw, 46px); letter-spacing: .28em; margin-right: -.28em; } .mrow.mnext { --c: var(--amber); } .mgoal { display: flex; align-items: baseline; gap: 8px; } .mgoal i { flex: none; width: 7px; height: 7px; border: 1px solid var(--muted); transform: translateY(-1px); } .mgoal.done { color: var(--text); } .mgoal.done i { background: var(--amber); border-color: var(--amber); }