Designing SASS Utilities and Runners like Tailwind
Why OCS pages should name ready-made SASS classes instead of pasting CSS, in three ideas you can try live, plus a homework lab with a real SASS compiler.
AP CSA Units 1–3 · OCS-UI Systems
Every OCS page needs buttons, cards, and colors. You can paste CSS into each page, or you can name a class that is already built. Today you will see why the class wins. Then you will build with classes yourself, and the build that has zero CSS earns a Jolly Rancher.
Explain why OCS pages should name shared SASS classes instead of pasting CSS, then build with those classes and add a new one.
Success criteria- I can explain why a class is a reference and pasted CSS is a copy.
- I can trace my theme color from a Java POJO to an
ocs__btn. - I can build a card with zero CSS and earn a Jolly Rancher.
- I can add a new style by adding a row of SASS data.
Start Here: The Jolly Rancher Survey
When you style something on your OCS page, what do you reach for? Be honest. There is candy involved.
A
style="..." attribute or a <style> block with my own colors and sizes.Classes that are already built, like
class="ocs__btn small".Words for Today
style="color: red", is an inline style.class="..." list. Spaces separate them, so class="ocs__btn medium" names two classes. Each name points at CSS rules.$. Browsers cannot read SASS, so each time GitHub rebuilds the site, SASS becomes plain CSS.--pref-accent-color that stays in the page. The browser looks it up while the page is open, so changing it changes everything that reads it.px-4 for padding, that many websites use (Tailwind Labs, n.d.-a).What OCS SASS Components Can Make
Every piece in the box below comes from class names in _sass/open-coding/, except one impostor. We built that one with pasted CSS, on purpose.
Spot the impostor. One button in the top row was built by pasting CSS. Which one? Guess, then switch the theme.
Idea 1: Reuse It
A class is a reference. Pasted CSS is a copy.
style="..." pastes a copy of a look into one tag. The next tag needs its own copy.class="ocs__btn medium" points at one look that lives in one SASS file. Every tag that names it shares it.The OCS SASS guide, _sass/open-coding/README.md, sets the goal: “OCS grammar is intended to help you build interesting pages with zero custom CSS.” Today you will see why.
How we counted
We checked every .md and .ipynb file that Git tracks under _notebooks, _posts, _projects, and navigation on the main branch of the OCS pages repo: 788 files. Copies made by the site build are not tracked, so they are not counted. A file counts if it has a style="..." attribute or a <style> block anywhere, even inside a code example. Colors are the six-digit hex codes inside that CSS, like #3b82f6.
Popcorn Hack 1: The Restyle Race (3 minutes)
Race a partner, each on your own laptop. One of you is Team CSS and one is Team SASS. Both teams edit plain HTML in the runner below. Spoiler: it is not a fair race. That is the point.
- Round 1: make your team’s three buttons red. Team CSS changes the colors inside each
style="...". Team SASS changesalert-greentoalert-red. - Round 2: make them filled. Team CSS adds a background color to each style. Team SASS adds the word
fillto each class list.
Press Run (▶) after every edit. Hands up when your team is done.
HTML Runner Challenge
Restyle Race. Round 1: make your team's three buttons red. Round 2: make them filled. Press Run after every edit.
View IPYNB Source
%%html
<!-- CODE_RUNNER: Restyle Race. Round 1: make your team's three buttons red. Round 2: make them filled. Press Run after every edit. | autostart: true, output_height: 270px -->
<div class="ocs__card">
<!-- TEAM CSS: edit the style attributes -->
<div class="ocs__section-title">Team CSS</div>
<div class="ocs__links">
<button style="border:2px solid #4ade80; color:#4ade80; background:transparent; border-radius:12px; padding:7px 14px;">Save</button>
<button style="border:2px solid #4ade80; color:#4ade80; background:transparent; border-radius:12px; padding:7px 14px;">Share</button>
<button style="border:2px solid #4ade80; color:#4ade80; background:transparent; border-radius:12px; padding:7px 14px;">Submit</button>
</div>
<!-- TEAM SASS: edit the class lists -->
<div class="ocs__section-title">Team SASS</div>
<div class="ocs__links">
<button class="ocs__btn medium alert-green">Save</button>
<button class="ocs__btn medium alert-green">Share</button>
<button class="ocs__btn medium alert-green">Submit</button>
</div>
</div>
What just happened? Open after the race.
Team SASS changed one word per button in each round, using names from a menu that already exists. Team CSS edited six color values in round 1, then had to invent a fill color in round 2. Look closely, too: Team CSS’s red is probably not the OCS red. And if OCS ever changes alert-red, Team SASS’s buttons change with it, because they point at the shared rule. Team CSS’s copies never will.
Java Twin: You Already Know References
In Java, “two different variables can hold references to the same object” (College Board, 2025, 2.6.B.1). Change the object through one variable, and the other variable sees the change.
A class attribute works like a shared reference. Pasted CSS works like giving every tag its own separate object. Predict both lines before you press Run.
Code Runner Challenge
Predict both lines, then run. Then change inlineButtons[0] to inlineButtons[2] and predict again.
View IPYNB Source
// CODE_RUNNER: Predict both lines, then run. Then change inlineButtons[0] to inlineButtons[2] and predict again.
public class ReferenceVsCopy {
public static void main(String[] args) {
// class="..." : three buttons share ONE Look object
Look shared = new Look("blue");
Look[] classButtons = {shared, shared, shared};
// style="..." : three buttons, three separate copies
Look[] inlineButtons = {new Look("blue"), new Look("blue"), new Look("blue")};
shared.setColor("green"); // edit the shared look once
inlineButtons[0].setColor("green"); // edit one copy
System.out.print("class buttons: ");
for (Look button : classButtons) {
System.out.print(button.getColor() + " ");
}
System.out.print("\ninline buttons: ");
for (Look button : inlineButtons) {
System.out.print(button.getColor() + " ");
}
System.out.println();
}
}
// A tiny POJO: one private field, a constructor, a getter, and a setter.
// Not public: a .java source can have only one public class, and that is ReferenceVsCopy.
class Look {
private String color;
public Look(String color) {
this.color = color;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}
ReferenceVsCopy.main(null);
Notice: all three class buttons turned green from one setColor call, because they hold the same reference. Only one inline button changed, because each one is its own object. Change .ocs__btn in one SASS file, and every ocs__btn button on OCS changes the same way.
Idea 2: Theme It
One value from a Java POJO colors every component that reads it.
UserPreferences, in a field named accentColor.--pref-accent-color..ocs__btn uses var(--pref-accent-color), so every component that reads it changes at once.Step 1, the POJO, trimmed from UserPreferences.java in the OCS Spring backend (comments added):
@Data // Lombok writes the getters and setters when this compiles
@Entity // Spring saves this object in the database
public class UserPreferences {
// ...
private String accentColor = "#3b82f6";
// ...more fields, like backgroundColor, textColor, and fontSize
}
Step 3, the class, from _sass/open-coding/elements/buttons/_api.scss:
.ocs__btn {
@include text-button;
--ocs-btn-tone: var(--pref-accent-color);
border-color: var(--pref-accent-color);
text-decoration: none;
}
See every file on the trip
UserPreferences.javastoresprivate String accentColor = "#3b82f6";.UserPreferencesApiController.javaanswersGET /api/user/preferences. It builds JSON from the POJO’s getters, likegetAccentColor(), which Lombok wrote. An API is a URL the page can ask for data. JSON is text that lists an object’s fields.assets/js/pages/dashboard/preferences.jsruns on Dashboard → Preferences. It reads the JSON,accent: backendPrefs.accentColor || d.accent,(the||means “use the saved color, or a default if there is none”), and saves a copy in your browser.assets/js/user-preferences.jsruns on every page. It reads that copy and sets the CSS variable:set('--pref-accent-color', accent);._sass/open-coding/elements/buttons/_api.scssis where.ocs__btnreadsvar(--pref-accent-color).
Not every class follows your theme, and that is on purpose. Alert tones like alert-red use site colors such as --red, which are the same for everyone, because red should always mean danger. They are still CSS variables, defined once for the whole site.
Popcorn Hack 2: Be the Backend (2 minutes)
Pretend you are the Spring backend. The buttons are plain HTML. The short script at the bottom plays two parts: the JSON the backend sends, and user-preferences.js.
- Change
accentColorto any color, like"#f72585"(Cyberpunk). Keep the#and the quotes. Press Run (▶). - One button ignores your POJO. Fix it: replace its whole
style="..."withclass="ocs__btn medium accent". Run again.
Typing a hex code is fine here. It is data stored in the POJO, not a style. The no-hex rule is about styles.
HTML Runner Challenge
Be the Backend. Change accentColor to your favorite color and run. Then fix the button that ignores the POJO.
View IPYNB Source
%%html
<!-- CODE_RUNNER: Be the Backend. Change accentColor to your favorite color and run. Then fix the button that ignores the POJO. | autostart: true, output_height: 220px -->
<div class="ocs__card">
<div class="ocs__links">
<button class="ocs__btn medium accent">Save</button>
<button class="ocs__btn medium accent fill">Submit</button>
<button style="height:35px; padding:7px 14px; border:1px solid #3b82f6; border-radius:12px; background:#0b1220; color:#3b82f6;">Share</button>
<span class="ocs__status">synced</span>
</div>
<label class="ocs__toggle"><input class="ocs__toggle-input" type="checkbox" checked><span class="ocs__toggle-track"></span><span class="ocs__toggle-label">Follow my theme</span></label>
</div>
<script>
// Pretend the backend sent this. The real JSON has more fields, like fontSize.
const prefs = { "accentColor": "#3b82f6" };
// user-preferences.js does this for the whole page. Here it is done for this output box.
outputElement.style.setProperty('--pref-accent-color', prefs.accentColor);
</script>
What just happened? Open after the hack.
Your one value traveled into both class buttons, the status, and the toggle. The “Share” button ignored it until you gave it classes. Then it joined the theme like everything else.
Idea 3: Generate It
Need a new style? Change the data, not the page.
.ocs__btn.small, .medium, and .large by hand. The OCS SASS has a table of numbers and a loop. SASS did the typing.The data. $sizes is a SASS map: a table of named rows, from _sass/open-coding/elements/buttons/_tokens.scss. SASS variables like $sizes start with $. They are used up when the site is built, so they never reach your browser.
$sizes: (
/* height, vertical padding, horizontal padding, border radius, text size, line height */
small: (28px, 4px, 10px, 40px, 15px, 20px, -0.23px),
medium: (35px, 7px, 14px, 12px, 15px, 20px, -0.23px),
large: (50px, 14px, 20px, 12px, 17px, 22px, -0.43px)
);
The loop, from _utilities.scss. @each works like Java’s for (String name : names): it runs once per row. #{$name} pastes the row’s name into the selector, the part before { that says which tags the rule styles. nth($values, 1) reads the row’s first value. SASS counts from 1, not 0 like Java.
@each $name, $values in $sizes {
.ocs__btn.#{$name} {
height: nth($values, 1);
padding: nth($values, 2) nth($values, 3);
border-radius: nth($values, 4);
border-style: solid;
border-width: 1px;
font-size: nth($values, 5);
line-height: nth($values, 6);
letter-spacing: nth($values, 7);
}
}
The output. Each time GitHub rebuilds the site, SASS writes plain CSS into style.css. This is the rule it wrote for the first row, copied from the live site. .ocs__btn.small means “any tag with both the ocs__btn and small classes.”
.ocs__btn.small, .small.iridescent {
height: 28px;
padding: 4px 10px;
border-radius: 40px;
border-style: solid;
border-width: 1px;
font-size: 15px;
line-height: 20px;
letter-spacing: -0.23px; }
Fine print, for the curious
- The
$sizescomment names six columns. The seventh value is the letter spacing. _utilities.scssloops over$sizestwice: once for plain.small,.medium, and.largeclasses any control can use, and once for theocs__btnversions shown above.- The extra
.small.iridescentappears because another style reuses everyocs__btnrule with SASS@extend. - SASS list positions start at 1 (Sass, n.d.-b), and
@eachcan walk a map’s keys and values together (Sass, n.d.-a). - The word
smallnames a whole row of values. College Board calls this data abstraction: “giving data a name without referencing the specific details of the representation” (College Board, 2025, 3.1.A.2).
bg-blue-500 (Tailwind Labs, n.d.-b). One difference: a Tailwind class like px-4 does one job, left and right padding. An OCS word like small sets a whole row.@Data on UserPreferences makes Lombok write the getters and setters from the fields when the code compiles (Project Lombok, n.d.). You write the data. A tool writes the repetitive code.The Rules for a Compatible Tweak
When OCS needs a new look, these three rules keep it working on every page and in every theme.
var(--teal), or the theme color var(--pref-accent-color). Never a typed hex code.ocs__grid and ocs__btn (Open Coding Society, 2026b).Popcorn Hack 3: Compile a New Size (3 minutes)
This box is a SASS runner, a real SASS compiler. It was built for this lesson from the same runner parts as the Java runners above.
- Add an
xlargerow with five values, like the other rows. Make its height more than 50px. - Press Run (▶). Read the compiled CSS and the live preview.
- Keep going until every check says PASS.
Your new size also works with tones that already exist, like alert-green fill. You changed one row of data and got a class that fits.
SASS Runner: Compile a New Size
Add an xlarge row with five values and a height over 50px. Press Run until every check says PASS.
The Jolly Rancher Challenge
Same deal as the survey: SASS classes earn candy, and pasted CSS earns nothing. Build a card about you with zero CSS. The checker under the runner decides.
____ blank with your own words.style="...", and there is no candy.The class menu. These all appear in the showcase at the top of this page.
| You want | Write this |
|---|---|
| A card around everything | <div class="ocs__card"> |
| A small label | <span class="ocs__badge"> |
| Big intro text | <p class="ocs__lead"> |
| A row of buttons | <div class="ocs__links"> |
| A button | <button class="ocs__btn medium accent">, with a size (small, medium, or large) and a tone (accent, alert-red, alert-yellow, or alert-green), plus fill or pill if you like |
| Stat tiles | <div class="ocs__stats"> holding tiles: <div class="ocs__stat"> with an ocs__stat-value and an ocs__stat-label |
| A status | <span class="ocs__status"> |
HTML Runner Challenge
Jolly Rancher Challenge. Build a card about you with zero CSS. Press Run, then read the candy checker under the runner.
View IPYNB Source
%%html
<!-- CODE_RUNNER: Jolly Rancher Challenge. Build a card about you with zero CSS. Press Run, then read the candy checker under the runner. | autostart: true, output_height: 380px -->
<!-- JOLLY RANCHER CHALLENGE: make this card about you.
Use only OCS classes. No style attributes, no style tags. -->
<div class="ocs__card">
<span class="ocs__badge">CSA · Period ____</span>
<p class="ocs__lead">Hi, I'm ____. I like to build ____.</p>
<!-- 1. Buttons: every button needs ocs__btn plus a size (small, medium, or large) -->
<div class="ocs__links">
<button class="ocs__btn medium accent">My Portfolio</button>
<button style="border:1px solid #3b82f6; color:#3b82f6; background:transparent; border-radius:12px; padding:7px 14px;">Contact</button>
</div>
<!-- 2. Stat tiles: copy this tile, then make both tiles about you -->
<div class="ocs__stats">
<div class="ocs__stat"><span class="ocs__stat-value">3</span><span class="ocs__stat-label">projects shipped</span></div>
</div>
<!-- 3. Add a status: a span with the ocs__status class -->
</div>
Wrap-Up: Three Things to Remember
Exit Survey
Same question as the start. From now on, what will you reach for?
Homework Hacks: The SASS Lab
Practice with real compilers, right here: two SASS labs and one Java lab.
Lab A: Add a New Tone
rule 2: colors are CSS variables Add a fourth tone to $ocs-alert-buttons. Its color must be a CSS variable that OCS already defines. There are two kinds:
- A site color, the same for everyone:
--teal,--orange, or--blue. (The yellow row uses--warn, the site’s yellow.) - The theme color, which follows each student:
--pref-accent-color.
Pick a site color if the meaning should never change, like red for danger. Pick the theme color if it should match each student. After it compiles, press “Try Cyberpunk” in the preview to see which kind follows the theme.
Lab A: Add a New Tone
Add a fourth tone whose color is an OCS CSS variable, never a hex code. Press Run until every check says PASS.
Lab B: Add a Runner Control
runners Every runner control is ocs__btn utility plus one action word, and each control has its own icon. Here all the icons sit in one list, so a new control is one more row. Add a help control with a "?" icon. Keep the quotes, like the other rows. The preview puts your control in a real runner toolbar.
Lab B: Add a Runner Control
Add a help control whose icon is a question mark in quotes. Press Run until every check says PASS.
Lab C: Model a Button as a POJO
Java POJO UserPreferences stores a theme. Your ButtonStyle POJO stores one button’s look. Finish two parts:
- The constructor allows only
small,medium, orlarge. Any other size becomesmedium. Compare Strings with.equals, not==. toClassList()returns the classes in grammar order:ocs__btn, then the size, thenalert-plus the tone, thenfillonly whenfilledis true. One space goes between classes.
All five checks should say PASS. A FIX line shows what your code returned and what it should return.
Code Runner Challenge
Lab C. Finish the ButtonStyle POJO so all five checks say PASS
View IPYNB Source
// CODE_RUNNER: Lab C. Finish the ButtonStyle POJO so all five checks say PASS
public class ButtonStyleLab {
public static void main(String[] args) {
ButtonStyle done = new ButtonStyle("large", "green", true);
ButtonStyle odd = new ButtonStyle("huge", "red", false);
ButtonStyle built = new ButtonStyle(new String("small"), "yellow", false);
check("large green filled button", done.toClassList(), "ocs__btn large alert-green fill");
check("unknown size becomes medium", odd.getSize(), "medium");
check("medium red button, not filled", odd.toClassList(), "ocs__btn medium alert-red");
check("a String built with new still counts (use .equals)", built.getSize(), "small");
odd.setFilled(true);
check("setFilled(true) adds fill", odd.toClassList(), "ocs__btn medium alert-red fill");
}
// Prints PASS, or FIX with what your code returned and what it should return
public static void check(String label, String got, String want) {
if (got.equals(want)) {
System.out.println("PASS: " + label);
} else {
System.out.println("FIX: " + label + " (got \"" + got + "\", want \"" + want + "\")");
}
}
}
// A POJO: private fields, a constructor, getters, and setters.
// Not public: a .java source can have only one public class, and that is ButtonStyleLab.
class ButtonStyle {
private String size;
private String tone;
private boolean filled;
public ButtonStyle(String size, String tone, boolean filled) {
// TODO 1: allow only "small", "medium", or "large". Any other size becomes "medium".
this.size = size;
this.tone = tone;
this.filled = filled;
}
public String getSize() {
return size;
}
public void setFilled(boolean filled) {
this.filled = filled;
}
public String toClassList() {
// TODO 2: return the classes in grammar order (see the steps above).
return "";
}
}
ButtonStyleLab.main(null);
Grading Plan (1 Point Total)
| Part | Points | What earns the points |
|---|---|---|
| Popcorn Hack 1: Restyle Race | 0.1 | Screenshot: all three Team SASS buttons are red and filled. |
| Popcorn Hack 2: Be the Backend | 0.1 | Screenshot: your accent color, with “Share” fixed by class="ocs__btn medium accent". |
| Popcorn Hack 3: Compile a New Size | 0.1 | Screenshot: every check says PASS. |
| Jolly Rancher Challenge | 0.1 | Screenshot: your card, with the candy checker saying “Jolly Rancher earned”. Finish it at home if class ran out of time. |
| Lab A: New Tone | 0.2 | Screenshot: every check says PASS. Notes: your new tone row. |
| Lab B: Runner Control | 0.15 | Screenshot: every check says PASS, with the “?” control in the toolbar. |
| Lab C: ButtonStyle POJO | 0.25 | Screenshot: all five checks say PASS. |
| Total | 1.0 |
Before You Submit
- Every SASS lab and Lab C say PASS on every check.
- No
styleattribute and no hex code anywhere in your SASS. - Seven screenshots uploaded, and your new SASS rows pasted into the notes.
Lesson Design Notes
LxD cycle: how this lesson was designed
Empathize: More than a quarter of OCS page files contain their own pasted CSS: 217 of 788 when we counted on October 1, 2026, with at least 571 different hex colors. The misconception we target: “a class is just a label, and the real styling is the CSS I paste.” A pasted border or background color also ignores the theme each of us picks, and that is easy to miss.
Define:
- POV: CSA students who build OCS pages need to feel what pasted CSS costs, because the choice that looks fastest breaks themes and multiplies every later edit.
- Learning goal: Students will explain reference versus copy, trace a theme value from a Java POJO to a SASS component, and generate a new compatible class by changing SASS data.
Ideate:
- HMW question: How might we make students want to use the system, instead of just telling them to?
- Activities: a candy survey, an impostor hunt, a restyle race, a be-the-backend hack, a live SASS compiler, and a solo build where only zero-CSS work earns candy.
Prototype: this page. Three ideas, three popcorn hacks, the Jolly Rancher Challenge, and a homework lab with auto-checks, built only from ocs__ components.
Test: we collected feedback before teaching and revised the lesson twice. See “Feedback and revision” below.
Feedback and revision
Feedback 1: After the first CSA lessons this sprint, Mr. Mortensen asked for lessons that engage the class and use real, hands-on popcorn hacks. The Sprint 2 checklist says the same thing: “Engage students within five minutes.”
Revision 1: Our first draft taught five code examples and was mostly reading. We rebuilt it around three ideas, opened with a survey in the first minute, put a hands-on popcorn hack inside each idea, and moved practice into a homework lab with live compilers.
Feedback 2: Before we taught, Mr. Mortensen asked for two more things. Students should write HTML as plain HTML, the way a %%html notebook cell works, not inside quoted JavaScript strings. And every student should build something on their own, with Jolly Ranchers as the reward.
Revision 2: We added an HTML runner to OCS. A %%html notebook cell with a CODE_RUNNER comment now becomes an editable runner that renders plain HTML. Both UI popcorn hacks moved to it. We also added the Jolly Rancher Challenge, where a checker awards candy only to builds with zero CSS.
College Board alignment
Quotes are from the AP Computer Science A Course and Exam Description, effective fall 2025 (College Board, 2025). Exam weights are the approximate share of the multiple-choice section (p. 16): Unit 1 is 15–25%, Unit 2 is 25–35%, and Unit 3 is 10–18%.
| Topic | Learning objective or essential knowledge | What students do |
|---|---|---|
| 1.13 Object Creation and Storage | 1.13.B.1 “A variable of a reference type holds an object reference or, if there is no object, null.” (p. 46) | Predict and change which references share one object in the Idea 1 Java twin. |
| 2.6 Comparing Boolean Expressions | 2.6.B.1 “Two different variables can hold references to the same object. Object references can be compared using == and !=.” (p. 66) | Explain why three references show one change, and use .equals instead of == in Lab C. |
| 3.1 Abstraction and Program Design | 3.1.A.2 “Data abstraction manages complexity by giving data a name without referencing the specific details of the representation.” (p. 80) | Add a named row (xlarge, a new tone, help) and use the name instead of the values. |
| 3.3 Anatomy of a Class | 3.3.A “Develop code to designate access and visibility constraints to classes, data, constructors, and methods.” (p. 83) | Read the UserPreferences POJO and write the private-field ButtonStyle POJO. |
| 3.4 Constructors | 3.4.A “Develop code to declare instance variables for the attributes to be initialized in the body of the constructors of a class.” (p. 84) | Write the Lab C constructor that keeps size valid. |
The system in one table: inputs, processing, outputs, tradeoffs, impact
| What it is here | |
|---|---|
| Inputs | SASS maps like $sizes and $ocs-alert-buttons, and each student’s UserPreferences POJO |
| Processing | SASS runs @each loops when the site is built. At page load, user-preferences.js turns the POJO’s fields into CSS variables. |
| Outputs | Utility classes in style.css, and --pref-* CSS variables on the page that the ocs__ components read |
| Tradeoffs | A new look needs a SASS change, a review, and a rebuild instead of a quick inline style. Plain size names like .medium are global, so any element with that class gets button sizing. OCS keeps a compatibility layer so older Tailwind classes follow the theme. ocs__ classes read the CSS variables directly, so they need far fewer patches. |
| Impact | One change fixes every page that uses the class. Themes keep working for students who need a light background or a bigger font. |
Presenter notes: run of show and likely questions
Before class, press Reset on both survey boards, and use a browser with no saved theme so the impostor starts out looking identical.
Our plan runs about 25 minutes. If time is short, run the Java twin as a quick predict-and-reveal, and give the challenge 4 minutes.
| Time | What happens | Who |
|---|---|---|
| 0:00 | Jolly Rancher survey. Count hands with the +1 and +5 buttons. Candy for B. | Presenter 1 |
| 2:00 | Showcase. Students guess the impostor, then click Cyberpunk to reveal it. | Presenter 1 |
| 4:00 | Tech Talk, Idea 1, and the Restyle Race in pairs. Then run the Java twin together. | Presenter 2 |
| 9:00 | Idea 2: the three-step trip, then Be the Backend. | Presenter 2 |
| 13:00 | Idea 3: data, loop, output, then Popcorn Hack 3 live. | Presenter 3 |
| 17:00 | Jolly Rancher Challenge. Everyone builds alone. Walk the room. Candy only when the checker says “Jolly Rancher earned”. | Everyone |
| 22:00 | Wrap-up, exit survey, and the homework hacks. | Presenter 3 |
“Isn’t SASS just CSS?” SASS is a language that turns into CSS when the site is built. The real choice is a shared, named, theme-aware class versus a pasted, one-off style.
“Why didn’t the alert buttons change with the theme?” They use site colors like --red on purpose, so red means danger in every theme.
“Why does ocs__btn medium have a white border?” This shows without a saved theme. The plain .medium class, from the first $sizes loop, sets border: none. It comes after .ocs__btn in style.css with the same specificity, so the border falls back to the text color. Adding accent brings the theme border back.
“Where is accent in the grammar?” It is used all over OCS, but button-grammar.md does not list it yet.
“What if the system does not have what I need?” Follow the three tweak rules, then open an issue or a pull request for Mr. Mortensen to review.
“Why not just use Tailwind?” Both generate classes from data. ocs__ classes read OCS CSS variables, so they follow OCS themes with far fewer patches, while Tailwind classes read Tailwind’s own theme. In September 2026, the Capstone page was rebuilt with ocs__ grammar.
“Can I use a little CSS in the challenge?” No. That is the rule from the survey: CSS means no candy. If the class menu does not have what you need, OCS needs a new class, and Idea 3 shows how to add one.
“Why does my card follow my theme?” The HTML runner draws your HTML right into this page, so it reads the same CSS variables as everything else.
“Does SASS run in my browser?” Not normally. It runs once when the site is built. The lab loads a compiler into this page only so you can practice.
References
College Board. (2025). AP Computer Science A course and exam description [Effective fall 2025]. https://apcentral.collegeboard.org/media/pdf/ap-computer-science-a-course-and-exam-description.pdf
Open Coding Society. (2026a). Button grammar [Source code]. GitHub. https://github.com/Open-Coding-Society/pages/blob/main/_sass/open-coding/elements/buttons/button-grammar.md
Open Coding Society. (2026b). Remove tailwind [Commit to the Capstone page]. GitHub. https://github.com/Open-Coding-Society/pages/commit/c8399e312e7873af516d90d56d74c63dbc75f2ca
Open Coding Society. (2026c). OCS SASS elements, mixins, and runner styles [Source code]. GitHub. https://github.com/Open-Coding-Society/pages/tree/main/_sass/open-coding
Open Coding Society. (2026d). Open Coding Sass guide [Source code]. GitHub. https://github.com/Open-Coding-Society/pages/blob/main/_sass/open-coding/README.md
Open Coding Society. (2026e). UserPreferences.java [Source code]. GitHub. https://github.com/Open-Coding-Society/spring/blob/master/src/main/java/com/open/spring/mvc/userPreferences/UserPreferences.java
Project Lombok. (n.d.). @Data. https://projectlombok.org/features/Data
Sass. (n.d.-a). @each. Sass documentation. https://sass-lang.com/documentation/at-rules/control/each
Sass. (n.d.-b). Lists. Sass documentation. https://sass-lang.com/documentation/values/lists
Tailwind Labs. (n.d.-a). Styling with utility classes. Tailwind CSS. https://tailwindcss.com/docs/styling-with-utility-classes
Tailwind Labs. (n.d.-b). Customizing colors [Version 3]. Tailwind CSS. https://v3.tailwindcss.com/docs/customizing-colors
Submit Assignment
Self-Assessment
Rate your work on this assignment, then add a short reflection. All 5 fields are required before you can submit.
Need to update a submission later? Open the submissions dashboard.