Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,34 @@ live-size data behind the reference slice.

---

## Theming (colors) — mandatory for all UI

The app supports light and dark via `DayNight` (toggle in `MainActivity`), but most
screens historically hardcoded dark-tuned hex, so the light theme is broken wherever
that happens. We are migrating to one semantic colour-token system, screen by screen
(refactor-by-feature).

Rules for any new or migrated UI:

1. **No hardcoded colours.** No `#RRGGBB` in layouts and no `Color.parseColor("#…")`
/ `Color.WHITE` etc. in code. Reference a semantic token instead:
`@color/<token>` in XML, `ContextCompat.getColor(ctx, R.color.<token>)` in code.
2. **Every token has a light value in `values/colors.xml` and a dark twin in
`values-night/colors.xml`.** If you add a token, add both.
3. **Use the semantic families**: surfaces (`surface_background`, `surface_card`,
`surface_section`), text (`text_primary`, `text_secondary`, `text_disabled`,
`text_on_accent`), `accent`/`accent_muted`, status
(`status_success/warning/danger/info`), `divider_line`, and data-viz
(`chart_storage/ram/swap/os/maps/wiki/track`). Pick by role, not by look.
4. **Legitimately fixed colours stay fixed:** a QR must be black/white to scan, so
`qr_foreground`/`qr_background` are mode-independent (no `-night` override).
5. **Verify both modes** on a device before merge.

Legacy tokens (`dash_*`, `white`, `black`, `section_*`, `btn_*`) are retired as screens
migrate. Reference migration: the Dashboard (`fragment_dashboard` + `DashboardFragment`).

---

## Tech-debt watch list (controller) — opportunistic targets

Evident debt noticed while building the pilot. Chip away at these **only when
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,8 +283,8 @@ private void updateSystemStats() {
int baseColorSwap = ContextCompat.getColor(requireContext(), R.color.dash_bar_swap);
int baseColorStorage = ContextCompat.getColor(requireContext(), R.color.dash_bar_storage);

int warnColor = Color.parseColor("#FF9800"); // Orange
int dangerColor = Color.parseColor("#F44336"); // Red
int warnColor = ContextCompat.getColor(requireContext(), R.color.status_warning); // Orange
int dangerColor = ContextCompat.getColor(requireContext(), R.color.status_danger); // Red

// RAM Gauge (Warning at 90%, Danger at 95%)
int finalColorRam = memProgress >= 95 ? dangerColor : (memProgress >= 90 ? warnColor : baseColorRam);
Expand Down Expand Up @@ -344,9 +344,9 @@ private void updateSystemStats() {
if (batLevel <= 33) {
colorBattery = warnColor; // Orange (1-33%)
} else if (batLevel <= 66) {
colorBattery = Color.parseColor("#4CAF50"); // Green (34-66%)
colorBattery = ContextCompat.getColor(requireContext(), R.color.status_success); // Green (34-66%)
} else {
colorBattery = Color.parseColor("#2196F3"); // Blue (67-100%)
colorBattery = ContextCompat.getColor(requireContext(), R.color.status_info); // Blue (67-100%)
}

// Update the gauge with the newly assigned 4-parameter method
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Typeface;
Expand All @@ -30,7 +29,7 @@ public class ResourceGaugeView extends View {
private String centerText = "0%";
private String bottomText = "-- / --";

private int currentColor = Color.parseColor("#4CAF50");
private int currentColor;

public ResourceGaugeView(Context context, AttributeSet attrs) {
super(context, attrs);
Expand All @@ -40,10 +39,11 @@ public ResourceGaugeView(Context context, AttributeSet attrs) {
private void init(Context context) {
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
rectF = new RectF();
currentColor = androidx.core.content.ContextCompat.getColor(context, R.color.status_success);

bgArcPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
bgArcPaint.setStyle(Paint.Style.STROKE);
bgArcPaint.setColor(Color.parseColor("#333333"));
bgArcPaint.setColor(androidx.core.content.ContextCompat.getColor(context, R.color.chart_track));
bgArcPaint.setStrokeCap(Paint.Cap.ROUND);
bgArcPaint.setPathEffect(null);

Expand All @@ -57,16 +57,16 @@ private void init(Context context) {

percentPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
percentPaint.setTextAlign(Paint.Align.CENTER);
percentPaint.setColor(androidx.core.content.ContextCompat.getColor(context, R.color.dash_text_inverted));
percentPaint.setColor(androidx.core.content.ContextCompat.getColor(context, R.color.text_primary));
percentPaint.setFakeBoldText(true);

valuePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
valuePaint.setTextAlign(Paint.Align.CENTER);
valuePaint.setColor(Color.parseColor("#AAAAAA"));
valuePaint.setColor(androidx.core.content.ContextCompat.getColor(context, R.color.text_secondary));

titlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
titlePaint.setTextAlign(Paint.Align.CENTER);
titlePaint.setColor(Color.parseColor("#CCCCCC"));
titlePaint.setColor(androidx.core.content.ContextCompat.getColor(context, R.color.text_secondary));
titlePaint.setFakeBoldText(true);

// LOAD AND APPLY ORBITRON
Expand Down
14 changes: 7 additions & 7 deletions controller/app/src/main/res/layout/fragment_dashboard.xml
Original file line number Diff line number Diff line change
Expand Up @@ -117,14 +117,14 @@
android:layout_width="16dp"
android:layout_height="16dp"
android:src="@drawable/outline_android_wifi_3_bar_24"
app:tint="#888888"
app:tint="@color/text_secondary"
android:layout_centerVertical="true" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Wi-Fi"
android:textColor="#888888"
android:textColor="@color/text_secondary"
android:textSize="13sp"
android:layout_toEndOf="@id/ic_wifi"
android:layout_marginStart="6dp"
Expand Down Expand Up @@ -154,14 +154,14 @@
android:layout_width="16dp"
android:layout_height="16dp"
android:src="@drawable/outline_connect_without_contact_24"
app:tint="#888888"
app:tint="@color/text_secondary"
android:layout_centerVertical="true" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hotspot"
android:textColor="#888888"
android:textColor="@color/text_secondary"
android:textSize="13sp"
android:layout_toEndOf="@id/ic_hotspot"
android:layout_marginStart="6dp"
Expand Down Expand Up @@ -193,13 +193,13 @@
android:layout_width="16dp"
android:layout_height="16dp"
android:src="@drawable/outline_clock_arrow_up_24"
app:tint="#888888" />
app:tint="@color/text_secondary" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Uptime:"
android:textColor="#888888"
android:textColor="@color/text_secondary"
android:textSize="13sp"
android:layout_marginStart="6dp"
android:layout_marginEnd="8dp" />
Expand Down Expand Up @@ -339,7 +339,7 @@
android:layout_height="wrap_content"
android:text="@string/dash_offline"
android:background="@drawable/rounded_button"
android:backgroundTint="#555555"
android:backgroundTint="@color/surface_section"
android:textColor="@color/dash_text_primary"
android:fontFamily="@font/orbitron"
android:textSize="11sp"
Expand Down
23 changes: 23 additions & 0 deletions controller/app/src/main/res/values-night/colors.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,27 @@

<color name="divider_color">#444444</color>
<color name="dash_bar_bg">#333333</color>

<!-- Semantic theming tokens (dark) — twins of values/colors.xml -->
<color name="surface_background">#121212</color>
<color name="surface_card">#1E1E1E</color>
<color name="surface_section">#2A2A2A</color>
<color name="text_primary">#FAFAFA</color>
<color name="text_secondary">#BDBDBD</color>
<color name="text_disabled">#7A7A7A</color>
<color name="text_on_accent">#FFFFFF</color>
<color name="accent">#4CAF50</color>
<color name="accent_muted">#2E5A30</color>
<color name="status_success">#66BB6A</color>
<color name="status_warning">#FFB300</color>
<color name="status_danger">#EF5350</color>
<color name="status_info">#42A5F5</color>
<color name="divider_line">#333333</color>
<color name="chart_storage">#4DB6AC</color>
<color name="chart_ram">#FFB300</color>
<color name="chart_swap">#7986CB</color>
<color name="chart_os">#26C6DA</color>
<color name="chart_maps">#FF9800</color>
<color name="chart_wiki">#66BB6A</color>
<color name="chart_track">#333333</color>
</resources>
35 changes: 35 additions & 0 deletions controller/app/src/main/res/values/colors.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,41 @@

<color name="footer_text_color">#5F6368</color>

<!-- ============================================================= -->
<!-- Semantic theming tokens (light). Each has a values-night twin. -->
<!-- Rule: reference these, never a hardcoded hex. See CLAUDE.md. -->
<!-- ============================================================= -->
<!-- Surfaces -->
<color name="surface_background">#F4F5F7</color>
<color name="surface_card">#FFFFFF</color>
<color name="surface_section">#E8EAED</color>
<!-- Text -->
<color name="text_primary">#202124</color>
<color name="text_secondary">#5F6368</color>
<color name="text_disabled">#9AA0A6</color>
<color name="text_on_accent">#FFFFFF</color>
<!-- Brand / accent -->
<color name="accent">#2E7D32</color>
<color name="accent_muted">#A5D6A7</color>
<!-- Status -->
<color name="status_success">#2E7D32</color>
<color name="status_warning">#E65100</color>
<color name="status_danger">#C62828</color>
<color name="status_info">#1565C0</color>
<!-- Borders / dividers -->
<color name="divider_line">#E0E0E0</color>
<!-- Data-viz (categorical) -->
<color name="chart_storage">#00897B</color>
<color name="chart_ram">#FF8F00</color>
<color name="chart_swap">#5C6BC0</color>
<color name="chart_os">#00838F</color>
<color name="chart_maps">#EF6C00</color>
<color name="chart_wiki">#2E7D32</color>
<color name="chart_track">#C4C7CC</color>
<!-- Fixed (NOT theme-dependent: a QR must stay black/white to scan,
so these intentionally have no values-night override). -->
<color name="qr_foreground">#000000</color>
<color name="qr_background">#FFFFFF</color>
</resources>


Loading