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.

Learning objective

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

Hands up · 1 minute

When you style something on your OCS page, what do you reach for? Be honest. There is candy involved.

A. I paste CSS
A style="..." attribute or a <style> block with my own colors and sizes.
B. I name ready-made classes
Classes that are already built, like class="ocs__btn small".
0A: paste CSS
0B: name classes
🍬 Raised your hand for B? Come get a Jolly Rancher. Everyone else, hold on. We ask again at the end of class.

Words for Today

CSSThe rules that say how a page looks: colors, sizes, and spacing. CSS pasted into one tag, like style="color: red", is an inline style.
classIn HTML, not Java: the names in a tag's class="..." list. Spaces separate them, so class="ocs__btn medium" names two classes. Each name points at CSS rules.
SASSCSS plus loops and variables that start with $. Browsers cannot read SASS, so each time GitHub rebuilds the site, SASS becomes plain CSS.
CSS variableA named value like --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.
POJOPlain Old Java Object: a class that just holds data in private fields, with getters and setters.
TailwindA popular kit of ready-made CSS classes, like 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.

Built from classes

Spot the impostor. One button in the top row was built by pasting CSS. Which one? Guess, then switch the theme.

Default theme: Midnight. These are the accent colors of real presets in Dashboard → Preferences.
The lineup
Sizes
Alert tones
Alert tones look the same in every theme, on purpose: red should mean danger everywhere.
Runner controls
Toggle, status, and badge
Stat tiles
105ocs__ class names
3button sizes
9runner controls
Holographic grid
data
loop
class

Idea 1: Reuse It

Tech Talk · Idea 1 of 3

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.
✓Change the shared look once and every page updates. Change a copy and only that one tag changes.
Pasted CSS adds up. More than a quarter of the page files in the OCS pages repo contain some: 217 of 788 when we counted on October 1, 2026, with at least 571 different hex colors.

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.

  1. Round 1: make your team’s three buttons red. Team CSS changes the colors inside each style="...". Team SASS changes alert-green to alert-red.
  2. Round 2: make them filled. Team CSS adds a background color to each style. Team SASS adds the word fill to 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>
Lines: 1 Characters: 0
HTML Output
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);
Lines: 1 Characters: 0
Output
Click "Run" in code control panel to see output ...

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

Tech Talk · Idea 2 of 3

One value from a Java POJO colors every component that reads it.

Pick a theme in Dashboard → Preferences, and your accent color takes a three-step trip.
1Java stores it. The Spring backend, the Java server behind OCS, keeps your theme in a POJO named UserPreferences, in a field named accentColor.
2The page turns it into a CSS variable. Dashboard → Preferences gets your theme from the backend and saves a copy in your browser. Every OCS page reads that copy and puts the color in --pref-accent-color.
3Classes read the variable. .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
  1. UserPreferences.java stores private String accentColor = "#3b82f6";.
  2. UserPreferencesApiController.java answers GET /api/user/preferences. It builds JSON from the POJO’s getters, like getAccentColor(), which Lombok wrote. An API is a URL the page can ask for data. JSON is text that lists an object’s fields.
  3. assets/js/pages/dashboard/preferences.js runs 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.
  4. assets/js/user-preferences.js runs on every page. It reads that copy and sets the CSS variable: set('--pref-accent-color', accent);.
  5. _sass/open-coding/elements/buttons/_api.scss is where .ocs__btn reads var(--pref-accent-color).
A border or background color typed as a hex code never asks the POJO, so it looks the same in every theme. Themes let students make OCS easier to read, like a light background or a bigger font, and a typed color ignores that choice. That is why the impostor did not change.

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.

  1. Change accentColor to any color, like "#f72585" (Cyberpunk). Keep the # and the quotes. Press Run (▶).
  2. One button ignores your POJO. Fix it: replace its whole style="..." with class="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>
Lines: 1 Characters: 0
HTML Output
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

Tech Talk · Idea 3 of 3

Need a new style? Change the data, not the page.

Nobody typed .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 $sizes comment names six columns. The seventh value is the letter spacing.
  • _utilities.scss loops over $sizes twice: once for plain .small, .medium, and .large classes any control can use, and once for the ocs__btn versions shown above.
  • The extra .small.iridescent appears because another style reuses every ocs__btn rule with SASS @extend.
  • SASS list positions start at 1 (Sass, n.d.-b), and @each can walk a map’s keys and values together (Sass, n.d.-a).
  • The word small names 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).
Tailwind does this too. Tailwind builds its classes the same way: a table of values plus a loop. Its version 3 palette has 22 colors in 11 shades each, which makes 242 shaded colors, and each one gets classes like 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.
So does Lombok, a Java library. The @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.

1Add data, not page CSS. A new row in a map becomes a new class.
2Colors are CSS variables: a site color like var(--teal), or the theme color var(--pref-accent-color). Never a typed hex code.
3Name it with the grammar, and propose it to Mr. Mortensen in an issue or a pull request, so every page can use it.
This is slower than one quick inline style: a SASS change, a review, and a rebuild. But one reviewed change fixes every page. Example: in September 2026, the Capstone page swapped its Tailwind classes for 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.

  1. Add an xlarge row with five values, like the other rows. Make its height more than 50px.
  2. Press Run (▶). Read the compiled CSS and the live preview.
  3. 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.

Lines: 1 Characters: 0
Compiled CSS
Press Run (▶) to compile. The first run loads the SASS compiler, which can take a few seconds.
Live preview not compiled yet
Checks

    The Jolly Rancher Challenge

    On your own · 5 minutes

    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.

    1Edit the HTML in the runner. Fill in every ____ blank with your own words.
    2Press Run (▶) after each change. The checks update every time.
    3When the checker says Jolly Rancher earned, raise your hand. A presenter checks your screen and hands you one.
    One trap: the starter came with a pasted-CSS button. Leave any CSS in, even one 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>
    
    Lines: 1 Characters: 0
    HTML Output
      Pass every check, with zero CSS, to earn a Jolly Rancher.

      Wrap-Up: Three Things to Remember

      1Reuse it. A class is a reference, and pasted CSS is a copy. Change the shared look once and every page updates.
      2Theme it. Your theme color starts in a Java POJO and reaches the page as a CSS variable. Classes read it. Typed hex colors never do.
      3Generate it. Need a new style? Add a row of data to the SASS, and let the loop write the class.

      Exit Survey

      Hands up again

      Same question as the start. From now on, what will you reach for?

      0A: paste CSS
      0B: name classes
      0B at the start
      Compare with the start. No candy this round: the candy went to the challenge, for zero CSS.

      Homework Hacks: The SASS Lab

      Homework hacks · about 20 minutes

      Practice with real compilers, right here: two SASS labs and one Java lab.

      1Edit the code in a lab and press Run (▶) to compile it.
      2Read the checks. Keep fixing until every check says PASS.
      3Press Save (💾) to keep your work in this browser. Careful: the trash button (🗑) resets a runner to its starter and erases what you saved.
      4Take screenshots of your Restyle Race output, your fixed Be the Backend output, your Jolly Rancher card with its candy checker, and the checks for Popcorn Hack 3, Lab A, Lab B, and Lab C. Upload them in the Submit Assignment form at the bottom of this page, and paste the SASS rows you added into the notes box.
      These labs use Dart Sass, today's version of SASS, so it can run in your browser. OCS builds its own SASS with Ruby Sass 3.7, an older version of the same language. Everything in these labs works in both. Want more grammar practice? The SASS Buttons and SASS Grids lessons go deeper.

      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.

      Lines: 1 Characters: 0
      Compiled CSS
      Press Run (▶) to compile. The first run loads the SASS compiler, which can take a few seconds.
      Live preview not compiled yet
      Checks

        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.

        Lines: 1 Characters: 0
        Compiled CSS
        Press Run (▶) to compile. The first run loads the SASS compiler, which can take a few seconds.
        Live preview not compiled yet
        Checks

          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:

          1. The constructor allows only small, medium, or large. Any other size becomes medium. Compare Strings with .equals, not ==.
          2. toClassList() returns the classes in grammar order: ocs__btn, then the size, then alert- plus the tone, then fill only when filled is 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);
          
          Lines: 1 Characters: 0
          Output
          Click "Run" in code control panel to see output ...

          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 style attribute 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.

          Technical Excellence

          Rate the technical quality of your work on this assignment — your use of tools, problem-solving, and technical growth.

          1 Explore · 2 Understand · 3 Apply · 4 Analyze/Evaluate · 5 Create/Extend
          Communication

          Rate how clearly you communicated your work and process — explanations, documentation, and collaboration or help-seeking.

          1 Beginning · 2 Developing · 3 Consistent · 4 Strong · 5 Model
          Work Habits

          Rate your work habits on this assignment — time management, persistence, responsibility, and follow-through.

          1 Beginning · 2 Developing · 3 Consistent · 4 Strong · 5 Model
          AI Orchestration

          Rate how effectively you used AI tools to support your work — prompting, verifying, extending, or accelerating your development process.

          1 Explore · 2 Understand · 3 Apply · 4 Analyze/Evaluate · 5 Create/Extend
          Click to upload or drag and drop
          PDF, ZIP, images, documents, or Jupyter notebooks (.ipynb) (Max 10MB per file)

          Need to update a submission later? Open the submissions dashboard.