Lesson 10 / الدرس 10

Building a palette that survives / بناء لوحة ألوان تدوم

A palette is not a set of colours you like. It is a small set of named roles, each with a value for every theme you support, each measured — and it is built from the neutrals outwards, not from the brand colour inwards.

اللوحة ليست مجموعة ألوان تعجبك. بل مجموعة صغيرة من أدوار مسمّاة، لكل دور قيمة في كل سمة تدعمها، وكلٌّ مقيس — وهي تُبنى من المحايدات إلى الخارج، لا من لون العلامة إلى الداخل.

Most people start with the brand colour and work outwards, and end up with a page that is largely brand-coloured and impossible to read. Start with the neutrals instead — the page, the panel, the border, the text — because they are ninety percent of what a reader looks at, and get the accent last, when you know what it has to stand out against.

The order to build it in

  1. Two grounds and a line. The page background, the panel that sits on it, and the border between them. If the panel is not visibly not the page, the whole layout has nothing to stand on.
  2. Two text colours. Normal, and muted for secondary information. Both measured against both grounds — that is four checks, and people usually do one.
  3. One accent, and the colour that sits on it. A button needs a text colour that is readable against the accent itself, which is a pair most palettes forget until the button exists.
  4. Three states. Success, warning, danger — each measured on both grounds, each paired with a word or an icon so the colour is never the only signal.
<style>
  /* Roles, not hues. Every value measured, and the ratio recorded. */
  :root {
    --bg:      #eef1f6;
    --surface: #ffffff;
    --border:  #d9dde5;
    --text:    #151821;   /* 15.7:1 on bg */
    --muted:   #5b6478;   /*  5.2:1 on bg */
    --accent:  #1f5fd0;   /*  5.1:1 on bg */
    --on-accent: #ffffff; /*  5.8:1 on accent */
  }
  body { background:var(--bg); font-family:system-ui; padding:16px }
  .panel { background:var(--surface); border:1px solid var(--border);
           border-radius:8px; padding:16px; max-width:340px }
  .muted { color:var(--muted); font-size:14px }
  .btn { background:var(--accent); color:var(--on-accent);
         border:0; border-radius:6px; padding:8px 14px }
</style>

<div class="panel">
  <h3 style="margin:0; color:var(--text)">Order confirmed</h3>
  <p class="muted">Delivery on Thursday</p>
  <button class="btn">Track it</button>
</div>
Seven values, and the whole interface is built from them. Note --on-accent: the colour that goes on the accent is its own role, because white is readable on some accents and invisible on others, and nobody discovers that until the button exists.

A dark theme is not an inversion

Flipping every value gives you white text on black, which is harsher than the light theme ever was, and a brand colour that now glows. Dark themes want softer text — a light grey rather than pure white — and lighter, less saturated accents, because a saturated hue on a dark ground vibrates. Each theme is designed; neither is generated from the other.

Try it live / جرّب بنفسك

Preview / المعاينة

Check yourself / اختبر نفسك

1. Why build a palette starting from the neutrals rather than the brand colour?

2. What is "on-accent" and why does it need to be its own role?

3. Why is a dark theme not just the light theme inverted?

Your task / مهمتك

Build a seven-role palette as CSS variables for a light theme and a dark one, and use it to style one small panel. Record the measured ratio beside every value.

ابنِ لوحة من سبعة أدوار متغيراتٍ في CSS لسمة فاتحة وأخرى داكنة، واستخدمها لتنسيق لوحة صغيرة واحدة. وسجّل النسبة المقيسة بجوار كل قيمة.

  • Seven roles, named by job, defined for both themes سبعة أدوار، مسمّاة بالعمل، معرّفة للسمتين
  • A measured ratio in a comment beside every text and accent value نسبة مقيسة في تعليق بجوار كل قيمة نص وتمييز
  • The dark theme is designed, not generated by inverting the light one السمة الداكنة مصمَّمة لا مولَّدة بقلب الفاتحة
How do you want to submit? / كيف تريد التسليم؟