/* ============================================================ BI122G — Exercise 3 Palette from the university's own materials: #043554 the lecture deck's title-slide navy — masthead only #0969A8 HiS blue — the lecture-slide heading blue and the logo crest; the core, examinable track, plus structural rules and links #157539 HiS emerald — the side quests #B52E75 HiS ruby — reserved entirely for the protips graphite scale for text and rules. Track system: core blue edge on the page ground side quest green tinted panel, dashed green edge protip ruby tinted band, ruby edge Each is distinguished by form as well as hue, so the distinction survives greyscale printing. Type: Open Sans, as on the university site, with Cascadia Mono for terminal text — the face students see in VS Code. ============================================================ */ :root{ --paper: #FFFFFF; --surface: #F4F7FA; --sunk: #EAEFF4; --ink: #14181B; --ink-body: #313538; --ink-soft: #5C6165; --ink-faint: #7E858A; --rule: #DDE4EA; --rule-firm: #B4BFC7; --green: #157539; --green-tint: #EBF4EF; --green-edge: #9AC7AC; --blue: #0969A8; --blue-deep: #06507F; --blue-tint: #EAF3F9; --blue-edge: #9CC4DD; --ruby: #B52E75; --ruby-tint: #FBEEF4; --ruby-edge: #E2A8C6; /* which hue carries which track. Swap these two groups to flip it. */ --core: var(--blue); --core-tint: var(--blue-tint); --core-edge: var(--blue-edge); --side: var(--green); --side-tint: var(--green-tint); --side-edge: var(--green-edge); --term-bg: #17202A; --term-ink: #DDE4EA; --term-dim: #939CA3; --term-cue: #6FBCE8; --term-warn: #E8A26A; --logo-filter: none; --sans: "Open Sans", "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif; --mono: "Cascadia Mono", "Cascadia Code", ui-monospace, "SF Mono", Menlo, "DejaVu Sans Mono", Consolas, monospace; } @media (prefers-color-scheme: dark){ :root:not([data-theme="light"]){ --paper: #0B0F12; --surface: #151B20; --sunk: #05080A; --ink: #F4F7FA; --ink-body: #D6DEE4; --ink-soft: #A6B0B8; --ink-faint: #808A92; --rule: #242C33; --rule-firm: #3A444C; --green: #5DBE84; --green-tint:#0F2318; --green-edge:#35624A; --blue: #6FBCE8; --blue-deep: #A5D6F2; --blue-tint: #0F2331; --blue-edge: #35617E; --ruby: #E87AB0; --ruby-tint: #26141D; --ruby-edge: #7C4160; --term-bg: #161D22; --logo-filter: invert(1); } } :root[data-theme="dark"]{ --paper: #0B0F12; --surface: #151B20; --sunk: #05080A; --ink: #F4F7FA; --ink-body: #D6DEE4; --ink-soft: #A6B0B8; --ink-faint: #808A92; --rule: #242C33; --rule-firm: #3A444C; --green: #5DBE84; --green-tint:#0F2318; --green-edge:#35624A; --blue: #6FBCE8; --blue-deep: #A5D6F2; --blue-tint: #0F2331; --blue-edge: #35617E; --ruby: #E87AB0; --ruby-tint: #26141D; --ruby-edge: #7C4160; --term-bg: #161D22; --logo-filter: invert(1); } *{ box-sizing: border-box; } body{ margin: 0; background: var(--paper); color: var(--ink-body); font-family: var(--sans); font-size: 16.5px; line-height: 1.65; -webkit-font-smoothing: antialiased; } .sheet{ counter-reset: part; /* only the core parts take a number */ max-width: 58rem; margin: 0 auto; padding: 2.5rem 1.5rem 6rem; } /* ---------- masthead ---------- */ .masthead{ margin-bottom: 2.5rem; } .logo{ display: block; width: 13.5rem; max-width: 60%; height: auto; margin-bottom: 2.25rem; filter: var(--logo-filter); } .eyebrow{ font-size: .72rem; font-weight: 600; letter-spacing: .14em; text-transform: uppercase; color: var(--blue); margin-bottom: .5rem; } h1{ font-size: clamp(1.9rem, 4.6vw, 2.7rem); line-height: 1.14; font-weight: 700; /* white in the dark theme; a literal #fff would vanish on the light theme and in print, so this tracks the theme's strongest ink */ color: var(--ink); margin: 0 0 .9rem; letter-spacing: -.015em; } /* the masthead spans the full column; the reading measure applies to body copy further down, not to the title block */ .standfirst{ font-size: 1.08rem; color: var(--ink); max-width: none; margin: 0; border-top: 3px solid var(--blue); padding-top: 1rem; } /* ---------- generic type ---------- */ p{ margin: 0 0 1rem; max-width: 68ch; } h2, h3{ text-wrap: balance; } a{ color: var(--blue); text-underline-offset: .18em; } strong{ font-weight: 600; color: var(--ink); } code{ font-family: var(--mono); font-size: .87em; background: var(--sunk); border: 1px solid var(--rule); border-radius: 3px; padding: .06em .32em; white-space: nowrap; color: var(--ink); } h2 code, h3 code, .cmd code, .term code{ background: none; border: 0; padding: 0; } kbd{ font-family: var(--sans); font-size: .76em; font-weight: 600; background: var(--paper); border: 1px solid var(--rule-firm); border-bottom-width: 2px; border-radius: 4px; padding: .12em .45em; color: var(--ink); white-space: nowrap; } /* ---------- legend ---------- */ .legend{ display: grid; grid-template-columns: repeat(auto-fit, minmax(14.5rem, 1fr)); gap: .9rem; margin: 2.25rem 0 1rem; align-items: start; } .legend > div{ padding: .85rem 1rem; font-size: .88rem; color: var(--ink-soft); border-radius: 0 4px 4px 0; } .legend .l-core{ background: var(--core-tint); border: 1px solid var(--core-edge); border-left: 4px solid var(--core); } .legend .l-side{ background: var(--side-tint); border: 1px dashed var(--side-edge); border-left: 4px solid var(--side); } .legend .l-protip{ background: var(--ruby-tint); border: 1px solid var(--ruby-edge); border-left: 4px solid var(--ruby); } .legend b{ display: block; font-size: .68rem; letter-spacing: .14em; text-transform: uppercase; margin-bottom: .3rem; color: var(--ink); } .legend .l-core b{ color: var(--core); } .legend .l-side b{ color: var(--side); } .legend .l-protip b{ color: var(--ruby); } /* ---------- parts ---------- */ .part{ display: grid; grid-template-columns: 5rem 1fr; gap: 0 2rem; padding-top: 2.5rem; margin-top: 2.5rem; border-top: 1px solid var(--rule); } .part:first-of-type{ border-top: 2px solid var(--blue); } .part:not(.is-side){ counter-increment: part; } /* a side quest is not a step in the sequence, so it carries no number and its label sits out to the right, clear of the numbered spine */ .part.is-side{ grid-template-columns: 1fr 6rem; } .part.is-side > .body{ grid-column: 1; } .part.is-side > .rail{ grid-column: 2; text-align: right; align-items: flex-end; } .rail{ font-size: .67rem; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-faint); display: flex; flex-direction: column; gap: .4rem; padding-top: .5rem; } .rail .num::before{ content: counter(part); } .rail .num{ font-size: 2.1rem; font-weight: 700; line-height: .9; letter-spacing: -.03em; color: var(--rule-firm); font-variant-numeric: tabular-nums; } .rail .tag{ font-weight: 700; } .rail .tag.core{ color: var(--core); } .rail .tag.side{ color: var(--side); } .part > .body{ min-width: 0; } .part h2{ font-size: 1.5rem; font-weight: 700; color: var(--core); margin: 0 0 .7rem; letter-spacing: -.012em; line-height: 1.2; } .part.is-side h2{ color: var(--side); } /* a whole side-quest part reads as one blue panel */ .part.is-side > .body{ background: var(--side-tint); border: 1px dashed var(--side-edge); border-left: 4px solid var(--side); border-radius: 0 5px 5px 0; padding: 1.2rem 1.4rem; } .part.is-side > .rail{ padding-top: 1.7rem; } /* ---------- tasks ---------- */ ol.tasks{ list-style: none; counter-reset: task; margin: 1.4rem 0; padding: 0; display: flex; flex-direction: column; gap: 1.3rem; } ol.tasks > li{ counter-increment: task; display: grid; grid-template-columns: 1.55rem 1fr; gap: 0 .8rem; min-width: 0; } ol.tasks > li::before{ content: counter(task); font-size: .72rem; font-weight: 700; color: var(--paper); background: var(--core); border-radius: 50%; width: 1.55rem; height: 1.55rem; display: grid; place-items: center; margin-top: .22rem; font-variant-numeric: tabular-nums; } .is-side ol.tasks > li::before{ background: var(--side); } ol.tasks > li > *{ grid-column: 2; min-width: 0; } ol.tasks > li > *:last-child{ margin-bottom: 0; } ol.tasks p{ margin-bottom: .6rem; } /* ---------- command + terminal blocks ---------- */ .cmd, .term{ margin: 0 0 .9rem; border-radius: 4px; font-family: var(--mono); font-size: .85rem; line-height: 1.7; position: relative; } .term{ overflow-x: auto; } /* the whole block is the copy target, so nothing prints that would not also work on paper */ .cmd{ background: var(--surface); border: 1px solid var(--rule); border-left: 3px solid var(--core); padding: .6rem 4.5rem .6rem .85rem; color: var(--ink); white-space: pre-wrap; overflow-wrap: anywhere; cursor: pointer; } .cmd::before{ content: "$"; color: var(--core); padding-right: .55rem; user-select: none; } .cmd::after{ content: "copy"; position: absolute; top: .45rem; right: .7rem; font-family: var(--sans); font-size: .6rem; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-faint); opacity: 0; transition: opacity .15s ease; } .cmd:hover::after, .cmd:focus-visible::after{ opacity: 1; } .cmd.copied::after{ content: "copied"; opacity: 1; color: var(--core); } .cmd:focus-visible{ outline: 2px solid var(--core); outline-offset: 2px; } /* inside blue territory the boxes sit on white so they stay legible */ .is-side .cmd, .side-quest .cmd{ background: var(--paper); border-left-color: var(--side); } .is-side .cmd::before, .side-quest .cmd::before{ color: var(--side); } .is-side .cmd.copied::after, .side-quest .cmd.copied::after{ color: var(--side); } .term{ background: var(--term-bg); color: var(--term-ink); padding: .8rem 1rem; white-space: pre; border: 1px solid var(--rule-firm); } .term .p{ color: var(--term-cue); } .term .c{ color: var(--term-ink); } .term .o{ color: var(--term-dim); } .term .e{ color: var(--term-warn); } .term .cap{ display: block; font-family: var(--sans); font-size: .62rem; font-weight: 600; letter-spacing: .13em; text-transform: uppercase; color: var(--term-dim); margin-bottom: .5rem; white-space: normal; } /* ---------- side quest ---------- */ .side-quest{ border: 1px dashed var(--side-edge); border-left: 4px solid var(--side); background: var(--side-tint); padding: 1rem 1.15rem; margin: 1.5rem 0; border-radius: 0 4px 4px 0; } /* nested inside an already-blue part, drop back to the page ground */ .part.is-side .side-quest{ background: var(--paper); } .side-quest > summary{ font-size: .71rem; font-weight: 700; letter-spacing: .13em; text-transform: uppercase; color: var(--side); cursor: pointer; list-style: none; display: flex; align-items: baseline; gap: .6rem; } .side-quest > summary::-webkit-details-marker{ display: none; } .side-quest > summary::after{ content: "optional"; font-size: .62rem; font-weight: 400; letter-spacing: .08em; color: var(--ink-faint); } .side-quest > summary:focus-visible{ outline: 2px solid var(--side); outline-offset: 3px; } .side-quest > *:not(summary){ font-size: .95rem; } .side-quest > summary + *{ margin-top: .85rem; } .side-quest > *:last-child{ margin-bottom: 0; } /* ---------- protip ---------- */ .protip{ background: var(--ruby-tint); border: 1px solid var(--ruby-edge); border-left: 4px solid var(--ruby); border-radius: 0 4px 4px 0; padding: .8rem 1rem; margin: 1.4rem 0; display: grid; grid-template-columns: auto 1fr; gap: 0 .9rem; align-items: start; } .protip.headline{ border-width: 2px; border-left-width: 5px; } .protip .keys{ display: flex; gap: .25rem; padding-top: .12rem; } .protip .said{ margin: 0; font-size: .94rem; color: var(--ink-soft); max-width: 62ch; } .protip .said b{ font-size: .67rem; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: var(--ruby); display: block; margin-bottom: .15rem; } .protip .said em{ font-style: italic; } /* ---------- misc blocks ---------- */ .note{ border-left: 3px solid var(--rule-firm); padding: .1rem 0 .1rem 1rem; margin: 1.3rem 0; color: var(--ink-soft); font-size: .95rem; } .note p:last-child{ margin-bottom: 0; } .callout{ background: var(--paper); border: 1px solid var(--core-edge); border-left: 4px solid var(--core); padding: 1rem 1.15rem; margin: 1.5rem 0; border-radius: 0 4px 4px 0; } .callout h3{ font-size: .71rem; font-weight: 700; letter-spacing: .13em; text-transform: uppercase; color: var(--core); margin: 0 0 .6rem; } .callout > *:last-child{ margin-bottom: 0; } table{ border-collapse: collapse; width: 100%; font-size: .91rem; } .tablewrap{ overflow-x: auto; margin: 1.3rem 0; } .tablewrap table{ min-width: 28rem; } th, td{ text-align: left; padding: .5rem .8rem .5rem 0; border-bottom: 1px solid var(--rule); vertical-align: top; } th{ font-size: .67rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-faint); border-bottom-color: var(--rule-firm); } td code{ white-space: nowrap; } ul.plain{ margin: 1rem 0; padding-left: 1.1rem; } ul.plain li{ margin-bottom: .45rem; max-width: 66ch; } /* ---------- closing ---------- */ .closing{ margin-top: 3.5rem; padding-top: 1.8rem; border-top: 2px solid var(--blue); } .closing h2{ font-size: 1.4rem; font-weight: 700; color: var(--blue); margin: 0 0 .8rem; } .colophon{ margin-top: 3rem; padding-top: 1rem; border-top: 1px solid var(--rule); font-size: .74rem; color: var(--ink-faint); display: flex; flex-wrap: wrap; gap: .3rem 1.5rem; } /* ---------- theme switch ---------- */ /* Built by sheet.js rather than written into the markup, so it exists only where it can actually work. It sits in the corner opposite the logo, above the reading column at every width. */ .themetoggle{ position: fixed; top: 1rem; right: 1rem; z-index: 10; width: 2.1rem; height: 2.1rem; display: grid; place-items: center; padding: 0; font-family: var(--sans); font-size: 1rem; line-height: 1; color: var(--ink-soft); background: var(--paper); border: 1px solid var(--rule-firm); border-radius: 50%; cursor: pointer; transition: color .15s ease, border-color .15s ease; } .themetoggle:hover{ color: var(--blue); border-color: var(--blue); } .themetoggle:focus-visible{ outline: 2px solid var(--blue); outline-offset: 2px; } /* ---------- narrow screens ---------- */ @media (max-width: 40rem){ body{ font-size: 16px; } .sheet{ padding: 2rem 1.1rem 4rem; } .part{ grid-template-columns: 1fr; gap: .7rem; } .rail{ flex-direction: row; align-items: baseline; gap: .85rem; padding-top: 0; } .part.is-side{ grid-template-columns: 1fr; } .part.is-side > .body, .part.is-side > .rail{ grid-column: auto; } .part.is-side > .rail{ padding-top: 0; text-align: left; align-items: flex-start; } .part.is-side > .body{ padding: 1rem 1.1rem; } .rail .num{ font-size: 1.4rem; } ol.tasks > li{ grid-template-columns: 1.4rem 1fr; gap: 0 .6rem; } .cmd{ padding-right: .85rem; } .cmd::after{ display: none; } } @media (prefers-reduced-motion: reduce){ *{ animation: none !important; transition: none !important; } } /* ---------- print / PDF ---------- */ @media print{ /* `:root[data-theme]` and not a bare `:root`: the dark blocks above are attribute-qualified, so they outrank a plain :root here and a reader printing while in dark mode would get a page flooded with ink. Equal specificity and later in the file, so print wins either way. */ :root, :root[data-theme]{ --paper: #fff; --surface: #F4F7FA; --sunk: #EEF2F6; --ink: #000; --ink-body: #1a1c1e; --ink-soft: #3a3d40; --ink-faint: #5a5e62; --rule: #c4ccd3; --rule-firm: #8d959b; --green: #0F5A2B; --green-tint: #EDF5F0; --green-edge: #86B69B; --blue: #06537F; --blue-tint: #EDF4F9; --blue-edge: #7FAECB; --ruby: #96225F; --ruby-tint: #FBEFF5; --ruby-edge: #C98BAE; --logo-filter: none; } body{ font-size: 10.5pt; background: #fff; } .sheet{ max-width: none; padding: 0; } .themetoggle{ display: none; } .cmd{ cursor: auto; } .cmd::after{ content: none; } .part{ break-inside: avoid-page; page-break-inside: avoid; } ol.tasks > li, .side-quest, .protip, .callout, .cmd, .term{ break-inside: avoid; page-break-inside: avoid; } .side-quest > summary::after{ content: " — optional"; } /* terminal blocks invert so they do not flood the page with ink */ .term{ background: #F2F5F8; color: #000; border: 1px solid #8d959b; } .term .p{ color: #06537F; } .term .o{ color: #44484b; } .term .e{ color: #8a3410; } .term .cap{ color: #5a5e62; } a{ color: #000; text-decoration: underline; } a[href^="http"]::after{ content: " (" attr(href) ")"; font-size: .8em; color: #5a5e62; word-break: break-all; } }