Own it · example handover · app/
src/demo.css
← All files · the demo this builds
/* Spreadsheet Rescue demo — scoped under .ssr. Art direction is the
argument: the "before" leans into fluorescent-office Excel grammar
(Calibri, gridline gray, that green); the "after" speaks the site's own
paper-and-ink language. The contrast does the selling. */
.ssr {
--paper: #fdfbf6;
--ink: #1d1a16;
--soft: #4f4a42;
--accent: #a23529;
--rule: rgba(29, 26, 22, 0.22);
--xl-grid: #d4d4d4;
--xl-head: #e9e9e9;
--xl-green: #217346;
--xl-select: #1a73c7;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
color: var(--ink);
text-align: left;
font-size: 0.95rem;
line-height: 1.45;
}
.ssr * { box-sizing: border-box; }
.ssr button { font: inherit; color: inherit; }
.ssr-kicker {
font-family: ui-monospace, Consolas, monospace;
font-size: 0.68rem;
text-transform: uppercase;
letter-spacing: 0.09em;
color: var(--soft);
margin: 0 0 0.5rem;
}
/* —— the frame: both worlds, one viewport —— */
.ssr-frame {
position: relative;
height: min(72vh, 540px);
border: 1px solid var(--rule);
border-radius: 6px;
overflow: hidden;
background: #fff;
touch-action: pan-y;
}
.ssr-before,
.ssr-after {
position: absolute;
inset: 0;
display: flex;
flex-direction: column;
}
.ssr-after {
background: var(--paper);
border-left: 0;
}
/* —— Excel grammar (the before) —— */
.ssr-before {
background: #fff;
font-family: Calibri, "Segoe UI", Arial, sans-serif;
font-size: 13px;
}
.ssr-fxbar {
display: flex;
align-items: center;
gap: 0;
border-bottom: 1px solid var(--xl-grid);
background: #f5f5f5;
flex: none;
}
.ssr-namebox {
width: 4.5em;
padding: 3px 6px;
border-right: 1px solid var(--xl-grid);
background: #fff;
font-size: 12px;
min-height: 1.6em;
}
.ssr-fx {
padding: 3px 8px;
font-style: italic;
font-family: Cambria, Georgia, serif;
color: #666;
border-right: 1px solid var(--xl-grid);
}
.ssr-formula {
flex: 1;
background: #fff;
padding: 3px 8px;
font-size: 12px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.ssr-sheetwrap {
flex: 1;
overflow: auto;
overscroll-behavior: contain;
}
.ssr-grid {
border-collapse: collapse;
table-layout: fixed;
}
.ssr-grid th,
.ssr-grid td {
border: 1px solid var(--xl-grid);
padding: 1px 4px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-weight: 400;
text-align: left;
height: 19px;
max-width: 16rem;
}
.ssr-colhead,
.ssr-rowhead,
.ssr-corner {
background: var(--xl-head);
color: #444;
text-align: center !important;
font-size: 12px;
position: sticky;
z-index: 1;
}
.ssr-colhead { top: 0; }
.ssr-rowhead { left: 0; min-width: 2.4em; }
.ssr-corner { top: 0; left: 0; z-index: 2; }
.ssr-cell { cursor: cell; background: #fff; }
.ssr-cell.is-num { text-align: right; }
.ssr-cell.is-err { letter-spacing: 0.02em; }
.ssr-cell.is-selected {
outline: 2px solid var(--xl-select);
outline-offset: -2px;
}
/* style table mirror — indices match fabricator's ST constants */
.ssr-cell.st-1 { background: #d9d9d9; font-weight: 700; }
.ssr-cell.st-2 { background: #edede3; font-weight: 700; text-align: center; font-size: 14px; }
.ssr-cell.st-3 { text-align: right; font-variant-numeric: tabular-nums; }
.ssr-cell.st-4 { text-align: right; }
.ssr-cell.st-5 { background: #fff066; text-align: right; font-variant-numeric: tabular-nums; }
.ssr-cell.st-6 { text-decoration: line-through; color: #808080; }
.ssr-cell.st-7 { text-decoration: line-through; color: #808080; text-align: right; }
.ssr-cell.st-8 { font-weight: 700; text-align: right; }
.ssr-cell.st-9 { font-weight: 700; text-align: right; font-variant-numeric: tabular-nums; }
.ssr-cell.st-10 { font-style: italic; color: #808080; }
.ssr-cell.st-11 { background: #fff066; }
.ssr-cell.st-12 { font-weight: 700; text-align: center; }
.ssr-cell.st-13 { font-weight: 700; color: #c00000; }
.ssr-tabs {
flex: none;
display: flex;
align-items: stretch;
gap: 0;
border-top: 1px solid var(--xl-grid);
background: #f0f0f0;
overflow-x: auto;
scrollbar-width: thin;
}
.ssr-tab {
border: 0;
border-right: 1px solid var(--xl-grid);
background: transparent;
padding: 4px 10px;
font-size: 12px;
white-space: nowrap;
cursor: pointer;
font-family: Calibri, "Segoe UI", Arial, sans-serif;
}
.ssr-tab.is-active {
background: #fff;
font-weight: 700;
box-shadow: inset 0 -2px 0 var(--xl-green);
}
.ssr-tab.was-hidden { color: var(--xl-green); font-style: italic; }
.ssr-unhide { color: #888; font-style: italic; }
/* —— the rebuilt app (the after) —— */
.ssr-app {
display: flex;
flex-direction: column;
height: 100%;
overflow: hidden;
}
.ssr-app-head {
flex: none;
padding: 0.5rem 0.75rem 0;
border-bottom: 1px solid var(--rule);
background: var(--paper);
}
.ssr-app-brand {
font-family: Charter, Cambria, Georgia, serif;
font-weight: 700;
margin: 0 0 0.4rem;
}
.ssr-app-tabs { display: flex; gap: 0.25rem; }
.ssr-app-tabs button {
border: 1px solid var(--rule);
border-bottom: 0;
border-radius: 5px 5px 0 0;
background: transparent;
padding: 0.25rem 0.7rem;
font-size: 0.82rem;
cursor: pointer;
color: var(--soft);
}
.ssr-app-tabs button.is-on {
background: #fff;
color: var(--ink);
font-weight: 600;
}
.ssr-jobs {
list-style: none;
margin: 0;
padding: 0 0.6rem;
overflow-y: auto;
flex: 1;
}
.ssr-jobrow { border-bottom: 1px solid rgba(29, 26, 22, 0.1); }
.ssr-jobrow.is-focus { background: #f3ecd8; }
.ssr-jobbtn {
display: flex;
width: 100%;
gap: 0.55rem;
align-items: baseline;
background: none;
border: 0;
padding: 0.45rem 0.1rem;
cursor: pointer;
text-align: left;
}
.ssr-jobno {
font-family: ui-monospace, Consolas, monospace;
font-size: 0.78rem;
color: var(--soft);
flex: none;
}
.ssr-jobmain { flex: 1; min-width: 0; }
.ssr-jobcust { display: block; font-weight: 600; font-size: 0.88rem; }
.ssr-jobcust em { font-style: normal; color: var(--soft); font-weight: 400; }
.ssr-jobdesc { display: block; font-size: 0.8rem; color: var(--soft); }
.ssr-recovered,
.ssr-cancelled {
display: inline-block;
font-family: ui-monospace, Consolas, monospace;
font-size: 0.62rem;
text-transform: uppercase;
letter-spacing: 0.06em;
border-radius: 3px;
padding: 0 0.35em;
margin-top: 2px;
}
.ssr-recovered { background: #e7efe2; color: #2e5b34; border: 1px solid #b9cfae; }
.ssr-cancelled { background: #f1e3e1; color: #8a3a30; border: 1px solid #d8b3ad; }
.ssr-jobside { flex: none; text-align: right; }
.ssr-status {
display: block;
font-size: 0.72rem;
font-weight: 600;
}
.ssr-status.s-Done, .ssr-status.s-Invoiced { color: #2e5b34; }
.ssr-status.s-Inprogress { color: #8a6116; }
.ssr-status.s-Scheduled { color: #34557e; }
.ssr-status.s-Onhold { color: #8a3a30; }
.ssr-jobdate { display: block; font-size: 0.75rem; color: var(--soft); font-variant-numeric: tabular-nums; }
.ssr-jobdate.is-focus, .ssr-detail .is-focus, .ssr-total.is-focus { background: #f3ecd8; }
.ssr-detail {
margin: 0 0 0.6rem;
padding: 0.4rem 0.5rem;
border: 1px dashed var(--rule);
border-radius: 5px;
font-size: 0.84rem;
}
.ssr-detail div { display: flex; gap: 0.6rem; padding: 0.1rem 0; }
.ssr-detail dt { color: var(--soft); min-width: 5.5em; }
.ssr-detail dd { margin: 0; }
.ssr-detail small, .ssr-total small { color: var(--soft); display: inline-block; }
.ssr-total {
flex: none;
margin: 0;
padding: 0.5rem 0.75rem;
border-top: 2px solid var(--ink);
font-variant-numeric: tabular-nums;
background: var(--paper);
font-size: 0.85rem;
}
/* the total's provenance receipt — tap the question, see the arithmetic */
.ssr-whence {
background: none;
border: none;
border-bottom: 1px solid var(--rule);
padding: 0;
font-size: 0.8rem;
color: var(--soft);
cursor: pointer;
}
.ssr-whence:hover { color: var(--ink); }
.ssr-whence-panel {
flex: none;
margin: 0;
padding: 0.5rem 0.75rem 0.6rem;
background: var(--paper);
border-top: 1px dashed var(--rule);
font-size: 0.8rem;
color: var(--soft);
}
.ssr-whence-panel p { margin: 0.2rem 0; }
.ssr-whence-panel table {
border-collapse: collapse;
font-variant-numeric: tabular-nums;
font-family: ui-monospace, Consolas, monospace;
font-size: 0.78rem;
color: var(--ink);
margin: 0.25rem 0;
}
.ssr-whence-panel td { padding: 0.05rem 0; }
.ssr-whence-panel td + td { text-align: right; padding-left: 1.25rem; }
.ssr-whence-sum td { border-top: 1px solid var(--ink); font-weight: 700; }
.ssr-sched {
margin: 0.5rem;
border-collapse: collapse;
font-size: 0.78rem;
overflow: auto;
display: block;
}
.ssr-sched th, .ssr-sched td {
border: 1px solid var(--rule);
padding: 0.3rem 0.4rem;
text-align: left;
vertical-align: top;
min-width: 7.5em;
}
.ssr-sched th[scope="row"] { min-width: 2.5em; }
.ssr-confirmed { color: #2e5b34; font-size: 0.7rem; display: block; }
/* —— the handle —— */
.ssr-handle {
position: absolute;
top: 0;
bottom: 0;
width: 36px;
margin-left: -18px;
cursor: ew-resize;
touch-action: none;
display: flex;
align-items: center;
justify-content: center;
z-index: 5;
}
.ssr-handle::before {
content: "";
position: absolute;
top: 0;
bottom: 0;
left: 50%;
width: 3px;
margin-left: -1.5px;
background: var(--ink);
box-shadow: 0 0 0 1px rgba(253, 251, 246, 0.7);
}
.ssr-grip {
position: relative;
background: var(--ink);
color: var(--paper);
border-radius: 50%;
width: 34px;
height: 34px;
display: grid;
place-items: center;
font-size: 1rem;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
}
.ssr-handle:focus-visible { outline: none; }
.ssr-handle:focus-visible .ssr-grip { outline: 2px solid var(--accent); outline-offset: 2px; }
.ssr-chip {
position: absolute;
top: 6px;
font-family: ui-monospace, Consolas, monospace;
font-size: 0.62rem;
text-transform: uppercase;
letter-spacing: 0.08em;
background: rgba(29, 26, 22, 0.78);
color: #fdfbf6;
padding: 2px 7px;
border-radius: 3px;
pointer-events: none;
z-index: 4;
}
.ssr-chip-left { left: 6px; }
.ssr-chip-right { right: 6px; }
/* —— tour + footer —— */
.ssr-tour {
display: flex;
flex-wrap: wrap;
gap: 0.4rem;
margin: 0.7rem 0 0.4rem;
}
.ssr-stop {
border: 1px solid var(--rule);
background: var(--paper);
border-radius: 999px;
padding: 0.25rem 0.75rem;
font-size: 0.8rem;
cursor: pointer;
}
.ssr-stop:hover { border-color: var(--ink); }
.ssr-stop.is-on {
background: var(--ink);
color: var(--paper);
border-color: var(--ink);
}
.ssr-caption {
margin: 0 0 0.9rem;
color: var(--soft);
font-size: 0.88rem;
min-height: 3.4em;
}
.ssr-foot { border-top: 1px solid var(--rule); padding-top: 0.8rem; }
.ssr-dl {
display: block;
width: 100%;
cursor: pointer;
background: var(--ink);
color: var(--paper);
border: 1px solid var(--ink);
border-radius: 5px;
padding: 0.6rem 1rem;
font-weight: 600;
box-shadow: 0 2px 0 rgba(29, 26, 22, 0.55);
}
.ssr-dl:active { transform: translateY(2px); box-shadow: none; }
.ssr-dl:disabled { opacity: 0.6; cursor: wait; }
.ssr-dl-note { margin: 0.5rem 0 0; font-size: 0.8rem; color: var(--soft); }
@media (prefers-reduced-motion: reduce) {
.ssr * { scroll-behavior: auto !important; }
}
/* standalone page only */
.ssr-standalone { margin: 1rem; background: #f7f3eb; }
.ssr-standalone [data-demo] { max-width: 46rem; margin: 0 auto; }
@media (max-width: 30rem) {
.ssr-frame { height: 76vh; }
.ssr-sched th, .ssr-sched td { min-width: 6em; }
}