900 || $value % 100 !== 0) { throw FrameworkException::create( ErrorCode::VAL_OUT_OF_RANGE, 'Font weight must be between 100 and 900 in steps of 100' )->withData(['value' => $value]); } } /** * Named font weights */ public static function thin(): self { return new self(100); } public static function extraLight(): self { return new self(200); } public static function light(): self { return new self(300); } public static function normal(): self { return new self(400); } public static function medium(): self { return new self(500); } public static function semiBold(): self { return new self(600); } public static function bold(): self { return new self(700); } public static function extraBold(): self { return new self(800); } public static function black(): self { return new self(900); } /** * Get named weight if applicable */ public function getNamedWeight(): ?string { return match ($this->value) { 100 => 'thin', 200 => 'extra-light', 300 => 'light', 400 => 'normal', 500 => 'medium', 600 => 'semi-bold', 700 => 'bold', 800 => 'extra-bold', 900 => 'black', default => null, }; } /** * Check if weight is bold or heavier */ public function isBold(): bool { return $this->value >= 700; } /** * Convert to SVG attribute value */ public function toSvgValue(): string { return (string) $this->value; } public function __toString(): string { return $this->getNamedWeight() ?? $this->toSvgValue(); } }