The Garage SDKs, in the open

garage_auth, garage_entitlements, garage_iap and garage_ui, moved out of
Garage-Services and Metro-Map-Maker into one public repo. MIT, one readme,
docs under docs/.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013F4NWNvYcdeSgqbWMT1VQ7
This commit is contained in:
ImBenji
2026-09-23 18:49:21 +01:00
co-authored by Claude Opus 5.5
commit b269201919
117 changed files with 26944 additions and 0 deletions
+88
View File
@@ -0,0 +1,88 @@
import "dart:ui" show Color;
import "package:flutter/widgets.dart" show Brightness;
import "package:garage_ui/theme/colour_scheme.dart";
/// Ready-made schemes, so a new app can look like a Garage app on line one.
///
/// Standing one up used to mean authoring 54 colours by hand before writing
/// any app code. These are the neutral pair, built through
/// [ColourScheme.derive] from four colours each — which is also the worked
/// example of how to make your own.
///
/// ```dart
/// GarageApp.router(
/// theme: ThemeData(colorScheme: GarageSchemes.dark),
/// ...
/// )
/// ```
///
/// Want your own hue? Change [ColourScheme.derive]'s `primary` and leave the
/// rest. Want one slot exact? Every derived slot has an override.
abstract final class GarageSchemes {
/// The neutral dark scheme. Same core Arcs & Angles' zinc is built on.
static final ColourScheme dark = ColourScheme.derive(
brightness: Brightness.dark,
background: const Color(0xff303030),
foreground: const Color(0xffe6e6e6),
primary: const Color(0xff4772b3),
);
/// The neutral light scheme — the same blue on a faintly cool near-white.
static final ColourScheme light = ColourScheme.derive(
brightness: Brightness.light,
background: const Color(0xfff2f2f4),
foreground: const Color(0xff1a1a1c),
primary: const Color(0xff3a63a1),
);
/// Carbon. True black, no chroma at all - built for oled panels, and the
/// scheme the Garage apps actually run.
///
/// It lives here rather than in each app because it didnt: the hub and Arcs
/// & Angles each kept their own copy and they drifted apart in twenty five
/// of fifty two slots before anyone noticed. One definition cant.
///
/// Carbon has 3.6 L* of room under its ground, against zinc's 19.9, so every
/// recessed rung squeezes into what there is - which is why chrome lands on
/// the floor without being told to. The pins are where carbon wants
/// something other than what the ladder gives it.
static final ColourScheme carbon = ColourScheme.derive(
brightness: Brightness.dark,
background: const Color(0xff0d0d0d),
foreground: const Color(0xfff2f2f2),
// no accent hue anywhere - primary is just a near white fill
primary: const Color(0xffe8e8e8),
primaryForeground: const Color(0xff000000),
ring: const Color(0xffffffff),
destructive: const Color(0xffc43333),
// the ladder puts these a shade off the floor. carbon wants the floor -
// the gutter between panels is the whole look.
popover: const Color(0xff000000),
controlFillFocused: const Color(0xff000000),
// above the ground rather than below it, which is what carbon has always
// done with muted. theres barely any "below" left to use.
muted: const Color(0xff0f0f0f),
controlFill: const Color(0xff080808),
tooltipBackground: const Color(0xff080808),
// NOT the ladder's +11.8 over the fill. Carbon cant recess a field far
// enough to read as recessed, so the stroke does all the separating and
// has to be the strongest thing on the control, not the weakest.
controlBorder: const Color(0xff2a2a2a),
chart1: const Color(0xfff45b69),
chart2: const Color(0xff86d957),
chart3: const Color(0xff62a7ff),
chart4: const Color(0xffffc857),
chart5: const Color(0xffff8c42),
);
/// Whichever of the pair matches [brightness].
static ColourScheme of(Brightness brightness) =>
brightness == Brightness.dark ? dark : light;
}