Massing baseline  /  Instant Fortress Rev AE — packaging envelope reopened

Fortress Form Study

Two wireless keyboard halves that clamp to the deck's edges, swing out like shutters, and lift off entirely. Orbit, pan, scrub the swing, pull the wings.

An ultrawide bar-panel deck. Two wireless keyboard halves clamp to its edges, swing out like shutters, and lift off entirely — leaving a touch tablet, and a split keyboard you can put anywhere on the desk.

Massing
322 × 147 × 46 mm; viewer baseline
CAD candidate
318 × 140 × 50→40 mm slab
Max span
643 mm across @175°
Mass
≈1.4 kg
Display
1920 × 720 exact touch kit unresolved
Compute
N100 16 GB, x86
Power
71.5 Wh, 12.1 W, ≈6.4 h
Keys
58 4×6 + 5 thumb
Cooling
Active heatsink + blower
Parts
≈$1080 USD core estimate

What it is for

A portable machine that is genuinely good at terminal work, editing and a browser — on a lap, on a train, or docked to a 2K panel. It is carried alongside a phone, not instead of one, and the heavy compute lives on a remote desktop.

Nobody sells this: an ultrawide bar panel, a split ergonomic keyboard that folds into the lid, ten-second battery swaps, and an expansion bay. That is the reason to build it — not to beat a GPD Pocket 4 on price, which it does not.

Design rules

  • Nothing crosses the hinges. Each wing is an independent wireless keyboard, so the hinge is chosen for one job instead of routing a flex cable.
  • Rails carry load, cables carry signal. No electrical contact in any mount — mechanical and electrical failures stay independent.
  • Separate in depth, not in plan. The rear face is contested; every feature has a depth budget below the local surface.
  • Fail safe, then optimize. A simple internal blower is the baseline; fan failure must throttle and shut down before batteries are heated.
  • Buy the standard, do not invent one. M-LOK, MIL-STD-1913, NP-F, USB, ZMK — every interface is someone else's problem already solved.
  • Measure, do not assert. Geometry claims are checked by a test suite; thermal and ergonomic claims are calculated and flagged as unmeasured.

Where it stands

CriterionStatusEvidence
Ultrawide bar panel, touchresolution selectedK003338 is the sourcing lead; mechanical drawings and Linux HID identity missing
Split ergo keyboard, detachablemodeled58 keys, 15° splay, ZMK, M-LOK clamps; hardware unbuilt
Hot-swap powerarchitecture selected3-source ORing, internal cells bridge the swap; bench proof pending
Expansion envelopemodeled3 USB-A + keyed PWR in replaceable blisters; hardware unselected
Runs Arch + Hyprland + VS Code + Zenplannedx86, 16 GB, dual 4K60 out; bench mule pending
Active airflow pathmet in model8 rear intake + 5 top exhaust slots
180–200° hinge assemblymodeled, hardware unproven7 mm relieved metal root leaf, inner wall and interleaved knuckles
Active cooling handles load safelyunmeasured8-slot intake, 5-slot exhaust; heatsink, blower and shutdown policy TBD
Everything fits insideCAD candidateofficial X4 STEP + aluminum frame fit; ten subsystem envelopes remain reserved, not measured
58 keys is livableuntestedmatches the Sofle count — start this today, it needs no new hardware

Nothing is built. Phase 0 is five tasks that fabricate nothing and any of which can still invalidate the design — and the first needs no hardware you do not already own. See the build spec for the full subsystem breakdown, BOM, risks and build order.

Your browser does not support the interactive canvas. The controls and specification remain available below.
DESK 625 × 130 MM
THICK 46 MM FOLDED / 32 OPEN
SWING 200°
drag to orbit 360° · shift- or right-drag to pan · scroll to zoom
Mode
Explode 0%
Swing 200°
Layout
Stand
Cover shut
View
Finish
Wings
Power
Modules
Soundbar mount
Bipods

Form mode. No concept modules attached.

Revision record — contains superseded dimensions and discarded approaches
QA

Geometry pass

You were seeing three separate bugs, and rather than nudge them by eye I wrote a test that can actually tell. A closed solid has a property worth checking: every directed edge must be used exactly once, and every edge must have a partner running the other way. An edge used twice the same way means two faces disagree about which side is out — that face gets backface-culled and reads as a missing surface. An edge with no partner is a literal hole.

Run against the old model, that test found 2,576 defective edges. The slab also computed to 1,644 cm³ against a physical envelope of about 930 — volume inflating like that is the signature of inconsistent normals. Three root causes:

  • Normals oriented against the wrong point

    Faces were wound outward relative to a single reference point per assembly, but each assembly is dozens of separate solids. For any part away from that centre — every bezel bar, every rim bar, every bay wall — the inward-facing walls got flipped and culled. This was most of the missing surfaces. Each primitive now orients against its own centroid, which is exact because they are all convex.

  • Corner cuts folding outlines into bow-ties

    The bezel and rim bars are about 9–10 mm deep but were asking for 12–28 mm corner chamfers, inherited from the body outline. A cut larger than the rectangle walks the outline back past its own start and produces a self-intersecting polygon — which lofts into exactly the loose shards you saw floating. Four of twenty outlines were doing this. Cuts are now clamped, and the bezel and rim are cut from the body outline by half-plane clipping instead, so the frame follows the corner flats properly rather than approximating them.

  • Chamfers wider than the thing being chamfered

    The chamfer ring is an inward offset, so asking for more than the shape can give turns it inside out. The glass at 0.4 mm thick with a 0.3 mm chamfer and the blister hatch at 0.6 mm with 0.8 mm were both inverted. Subtler: clipping a 22 mm corner flat left a 1 mm edge on one rim bar, and a 1.4 mm chamfer across that inverted it too. Chamfers are now clamped against thickness, inradius and shortest edge.

All tested assemblies now pass: zero defective edges, no holes, no inconsistent normals. The runner exercises the slab, both wings, clamp and pack across the supported corner states.

Three things were genuinely floating rather than merely broken, and those were design errors rather than code ones. The cam latch sat 7 mm off the front of the deck, attached to nothing — it is now a quarter-turn cam carried in each wing's own rim, dropping a pin into a strike in the bezel behind it. The encoder stood 1.5 mm proud of the wing rim, which would have borne on the deck when shut, breaking the rule the whole wing section is built around; it is now wholly inside the wing thickness. And the hinge knuckles stood 4.5 mm off the bezel plane and punched through the folded wings, so they are now sunk flush. A separate check confirms no part is left touching nothing.

Two smaller ones while I was in there: the rear fins overlapped the I/O shroud, and the port openings stood proud of it instead of sitting in it.

On the CAD. Happy to do it, and this pass is a fair sample of both what you would get and what to watch for. The useful part is not that the bugs got fixed — it is that they were found, by a check that answers a yes/no question about the mesh rather than by looking at it. Two of these three were invisible from the default view.

The same discipline carries into real CAD, where the equivalents are manifold and watertightness checks, wall-thickness minimums, and interference detection between bodies. Worth saying plainly though: this renderer is a massing tool with no boolean operations, so it cannot subtract a pocket from a solid — which is why recesses here are faked by building frames around openings. Real CAD gets that for free, and it is also where the internal volume check finally gets done properly.

FIXED

The fold was going the wrong way

You were right, and it was a real bug rather than a viewing angle. The wings were sweeping around the back of the deck to get to the closed position instead of arcing over the front.

What makes it a nasty one is that both endpoints were correct. Folded, the wings sat on the display; deployed, they lay out to the sides — so the checks I wrote passed. Only the path between was wrong. Traced through the swing, the right wing's tip was reaching 154 mm behind the screen plane at the halfway point, which is the wings taking the long way round. The rotation is now applied to the folded pose in the opposite sense, and the same trace shows the tip 154 mm out in front at halfway. I test the trajectory now, not just where it lands.

Two things fell out of the correction. Because the wings now arc over the front, the deployed stop sits on the near side of coplanar, so they finish with a slight forward cant — a 5° wrap that brings each outboard tip 13.5 mm toward you. That is the good direction: your hands come from outside, and the keyboard planes turn to meet them. It also means the earlier claim that the wings end up flatter than the display was backwards, and is gone.

KEYS

Yes — six columns and a thumb cluster fit

You spotted the same slack I did. The wings are 161 × 130 mm and the old 4 × 5 grid used barely half of that. The current model carries 4 rows × 6 columns plus a 5-key thumb cluster per hand — 29 per side, 58 total.

The reason this matters more than "more keys is nice": that is essentially your Sofle. Fifty-six against its fifty-eight, same four rows, same six columns, thumbs in the same place. Muscle memory transfers instead of being rebuilt, which quietly deletes the riskiest soft item in the plan — the two weeks of relearning a 40-key layout, and the chance you'd hate it after the PCBs were cut. Choc's 18 × 17 mm pitch is tighter than the Sofle's MX spacing, so it will feel more compact, but the map is the map.

Wing budgetmmNote
Wing width155fixed — two wings must cover a 310 mm slab
Rim, both sides−189 mm each; bears on the bezel
6 columns @ 18 mm−108the key field
TrackPoint zone−20outboard of the pinky column
Slack9tight but real

Vertically it is comfortable — four rows and the thumb arc use 90 mm of 112 mm available. Horizontally there are 9 mm to spare, so this is the ceiling: a seventh column would not fit alongside the pointer.

One consequence worth flagging, since it sharpens a concern I raised earlier rather than resolving it: the field is now 18 mm wider, so the TrackPoint sits further outboard and the reach from the home row gets longer. If a nub past the pinky column was marginal at five columns, it is more marginal at six. Same recommendation — settle it on a real split before cutting PCBs — but it now has more riding on it.

EXT

Back rails and the EXT ports

Two systems now, doing different jobs, which is the lesson from the DFCD: the side edges carry M-LOK for structure, the back carries Picatinny for accessories, and neither carries any electrical contact at all. Signals go over short external cables with circular push-pull connectors, exactly as that build does it.

The detail worth copying precisely is that the rail is the connector panel. On the DFCD each back rail carries a receptacle at each end with the label between them — PWR, EXT 1, EXT 2, EXT 3 — so one printed part is both the mounting surface and the I/O bulkhead. Same here: two rails flanking the camera bay, four ports, PWR and EXT 1 on the left, EXT 2 and EXT 3 on the right.

One departure, and it is an improvement on the original. The barrels exit the side of each rail rather than the back. Facing aft, a plugged cable gets bent through 90° the moment the deck is set down on it, and that bend lands exactly at the connector's strain relief — the worst place for it. Exiting sideways lets the cable run parallel to the back surface and reach a side module without a loop. The barrels point outboard, away from the centreline, so the run to a wing or a handle is as short as it can be.

That change also sets where the ports sit. The rail runs full height at each connector to house the barrel — 22 mm of rail width against a GX12's roughly 20 mm body — and the ports moved up to y = 40 and y = 112 so the outboard collars clear the cell blisters, which end at y = 28.

The back rails are free, and that is not a coincidence. An additive Picatinny rail stands about 12 mm proud — measured off their own files at 12.40 mm, which is exactly why we did not put it on the side edges. But the back already gives up 15 mm to the camera pack. A 12 mm rail hides entirely underneath that, so the maximum envelope does not move.

It nearly did. Modelling the connectors as proud bosses put them 20.6 mm out — past the pack, with the rails setting the envelope for the first time. That was my error rather than a design problem: a panel receptacle sits near-flush and only the mated plug protrudes, which is plainly what their photos show. With the barrels turned to exit sideways the whole assembly stands 8.8 mm, well inside the pack's 15 mm.

Signal split follows the bandwidth. EXT 1 and 2 are USB-A 3.0 at 10 Gbit/s; EXT 3 is USB-A 2.0 for LoRa, serial and low-speed input. All three carry gasketed screw caps. PWR is power only and stays a circular locking connector: an external NP-F module feeding the same 12 V rail.

And that external battery module still needs no design work. The staggered-setpoint ORing accepts arbitrary sources, so an external pack is one more ideal-diode branch at about 12.2 V — it outranks the internal cells, which then charge behind it.

Two things worth taking from their bill of materials as well. They use the Jupio NP-F970 with USB-C input — a pack that charges itself — which makes our internal camera-pack charger optional and leaves only the 18650s strictly needing one. And their power module sends 7.2 V raw to the chassis to be converted there rather than regulating at the pack, which is the same call we made independently.

HEAT

Three levers, and the aluminium one is nearly free

Not fan-and-pray. There are three independent levers, and the cheapest is not the one you asked about.

Lever 1 — buy a better converter

The DC-DC loss is entirely a purchasing decision, and it is the best return in the whole problem:

ConverterEfficiencyLoss at 10 WBody heat
Generic XL-series88%1.36 W9.5 W
Decent synchronous92%0.87 W9.0 W
TPS55289-class95%0.53 W8.6 W

0.8 W for about $10 of parts, and it is heat that never exists rather than heat you have to move. The spec already called for a synchronous converter; it now calls for a good one.

Lever 2 — a flat aluminium back, and nothing else

Built, and built the cheap way: one laser-cutting operation, no fins, no milling, no bonded extrusion. Fins were worth about 2.3 W but they need a second process, which is precisely the cost this is meant to avoid.

"Full aluminium back" is smaller than the phrase suggests. The rear face is 403 cm², but the camera bay, both cell blisters and the kickstand take about 40% of it — so this is five panels cut around them, not one rectangle:

PanelArea
Over the compute board95 cm²
Above the camera bay66 cm²
Right of the bay16 cm²
Between cell L and the rail7 cm²
Left of the bay4 cm²
Both rear rails, bolted to the sheet124 cm²
Total312 cm²

The rails count because bolting them to the sheet puts them at its temperature — they stop being decoration and become 40% of the radiating area. That also quietly re-does what decoupling the bottom rail undid, but on the two rails that were never the awkward L.

LoadBody heatSurface
Idle — SoC 2.5 W4.6 W38 °Ccomfortable
Light — SoC 4 W6.2 W42 °Ccomfortable
Full PL1, 95% converter8.6 W49 °Cwarm, under the 51 °C limit
Full PL1, 88% converter9.5 W51 °Cat the limit — do not

Dropping the fins costs 6 °C at full load, and nothing where you actually are. With the compute living on the Framework desktop, this deck spends its life at idle-to-light — 38–42 °C, which is cooler than a laptop palm rest.

It does make lever 1 mandatory rather than advisory. The gap between a 95% converter and an 88% one is now the gap between 49 °C and 51 °C — between "warm" and "at the burn threshold". That $10 stopped being an optimisation.

Lever 3 — the fan module, unchanged

Forced convection roughly doubles h, so the same 312 cm² becomes about 15 W. With no fins the fan has less surface to work across than it would have had, but 15 W is still far more than the deck can draw — and it is the honest answer for a sustained compile now that the passive case runs 49 °C.

Where that leaves it. Silent and fanless across the whole range this deck will actually live in, and warm-but-safe at the top of it. Not the 43 °C a finned back would have given, but bought with one laser-cut part instead of two processes.

But say the uncomfortable part plainly: every number here is calculated. h is assumed at 11.6, the interior is a lumped estimate, radiation between adjacent fins is not modelled (it will derate the fin figure somewhat), and lying the deck on a duvet defeats all of it. The margin is thin enough that the bench mule is now the thing that decides whether this design is fanless or not — which is why it sits at Phase 0 rather than anywhere later.

PWR

The two numbers really did disagree

Caught in outside review, and the criticism was exactly right: I had been quoting 71.5 Wh over 6.4 h — an 11.2 W system average — alongside a cooling budget of 6.5 W, and never said which was which. Decomposed:

SourceWLands in
SoC, N100 at PL16.0spreader — conducted out
DC-DC conversion loss1.4sealed bay
Panel driver board1.0sealed bay
Panel backlight2.6lid, over 292 × 110 mm
Radios0.6sealed bay
NVMe and misc0.5sealed bay
Total12.1vs 11.2 implied by runtime

The runtime figure survives; the thermal one does not. That is the opposite of what the review predicted, and it is the more awkward outcome.

12.1 W computed against 11.2 W implied is close enough that the 6.4 h stands. But the cooling budget was sized for the SoC alone. The body actually has to shed 9.5 W — everything except the backlight, which is in the lid — and 3.5 W of that was landing in a sealed plastic box with no conduction path at all. It was never counted because I only ever asked "can the spreader handle the processor".

Two consequences. The interior air now has a number: 3.5 W through interior convection, 3 mm of CF PETG and the outer surface is about 3.8 K/W, so it sits ~38 °C at 25 °C ambient. Electrolytics and inductors are comfortable there, so the sealed box survives — but that was luck rather than design.

The fin height was wrong. Sized against 6 W they were 9.25 mm; against 9.5 W they are 12 mm, level with the rails. That is worth 50 cm² and takes the passive figure to 7.7 W at a 45 °C surface. Level rather than below is deliberate: a deck laid on its back now shares the load with 21 mm of solid rail either side instead of resting on fin edges.

Which leaves the honest position: at full 6 W PL1 the aluminium sits around 50 °C. Below the 51 °C one-minute burn threshold, above the 43 °C indefinite-contact one, and these are the parts you hold. Idle and light use are comfortable — around 37–42 °C — and sustained load is where the fan module stops being optional. That was always the architecture; the correction is that the crossover is lower than I claimed.

HINGE

The hinge is not unsourced — I had not looked properly

The review's advice was to stop looking for a hinge, on the grounds that pivot-with-friction and release-on-demand are two mechanisms fighting for one volume. The premise does not quite hold here — this design already separates them, with the M-LOK cam clamp doing the release and the hinge only pivoting — but the prompt to look again was right, and the part exists.

Southco C6 / G6 detent hinges. 180° range of motion, multiple detent angles, three positioning torque ratings, stainless with acetal leaves, and available off the shelf. That is precisely the specification I have been calling unsourced for a dozen revisions: a positive detent rather than adjustable friction, which is what stops a wing creeping shut under hand pressure.

The 180° range also lines up exactly with the cap the clamp geometry already forced, so nothing has to change to accommodate it.

Still to check before this comes off the risk list: the torque rating against a 155 mm cantilevered wing, the leaf geometry against a 14 mm wing on a 6 mm offset, and whether a detent can be had at 180° rather than short of it. But "confirm a datasheet" is a different class of problem from "no such part exists", so the risk drops from High to Medium.

The suggested alternative — QD sling swivels — is worth keeping in the back pocket. It gives rotation and release in one $12 commodity part, and the axis works if the sockets go in the top and bottom edges with the studs vertical. Two reservations: sling swivels are built for tension rather than cantilever bending, and they have radial slop that a 130 mm hinge line would amplify. As a fallback if the Southco torque numbers disappoint, though, it is a good one.

SWING

They were stretching because they were not rotating

Both panels were driven by shearing z with y — the further a point sat from the hinge, the further out it was pushed. That moves the free edge but leaves every vertex at its original y, so the panel gets longer as it opens instead of swinging. It is the difference between tilting a plate and dragging its far edge backwards.

A real rotation moves both coordinates:

Shear (was)Rotation (now)
yhinge − dhinge − d·cos α
zsurface − d·ksurface − d·sin α
panel lengthgrows with kconstant

Both are now built flat in a local frame and mapped through that rotation. There is a detail worth keeping: the rear face rakes at 6.1°, so "lying flat against the shell" is not α = 0 — it is α = 6.1°, and the open angle is added to that. Otherwise the panel starts by lifting off the surface it is supposed to be resting on.

Length is now asserted rather than eyeballed: the kickstand's diagonal holds at 86.3 → 86.9 mm across the full sweep and the cover's at 30.3 → 30.6 mm, against 30.3 → 26.5 before. Writing that check also caught a bug in the check itself — at full open the cover shrinks in plan and my part-picker started grabbing the shroud behind it instead, which is why both panels now carry their own material.

CHG

Where to look for the USB-C

Top edge, far left, x 9–20 — the first feature past the corner, before the power button. Facing the screen, it is the top-left corner; from the rear it reads as top-right.

It now stands 3 mm proud, which makes it the tallest thing on that edge and easy to pick out along 310 mm of otherwise quiet surface. On the real part this would be a flush receptacle; here it is deliberately raised as a landmark, exactly as you suggested.

xFeatureProud
9–20USB-C PD charge in3.0 mm
26–34Power button1.1 mm
40–483.5 mm jack1.0 mm
52–55microSD1.0 mm
60–252M-LOK ×5flush
POSE

Poses, and two live sliders

Five named poses, plus sliders for the kickstand and the port cover. Stepping through the poses is the fastest way to catch a part that only works in one of them — which is exactly how the hinge clash and the connector collisions surfaced.

PoseWingsSwingStandWhat it is
Closedonfoldedin a bag — check nothing protrudes
Lapon175°foldedthe 5° wrap, held or on the knees
Deskon175°out5° forward wrap, propped
Tabletoffout310 × 147 mm maximum envelope, touch only
Serviceoffpartrear view, port cover open

The port cover is modelled now rather than omitted — hinged at y = 118 and swinging up, with its gasket landing on the shroud lip when shut.

DOWN

The lower ports face down — and the same bug, twice more

You were right on both counts. All four facing up would have put the lower collars straight into the rail above them, so the lower pair now faces down and the upper pair up. That also removed a leftover: the left rail's base extension ran down to y = 0 and sat exactly where the lower connector needs to exit. It was there to carry heat into the bottom rail, which we have just decoupled, so it went with it.

The invisible connectors were the buried-feature trap again, and this makes at least six times. The collars stopped inside their own bosses — a barrel that ends inside its housing cannot render, exactly like a bore inside a lug or a slot inside a shell.

Chasing it turned up a whole category I had missed: every top-edge feature was buried too. The power button, the 3.5 mm jack and the microSD slot were built as cylinders lying along the edge rather than standing up through it, so all three sat 1–8 mm inside the shell. The USB-C port was the only one that broke the surface, which is presumably why you could ask where the others were but not that one. All nine top-edge features now break the plane.

The rule, stated once so it stops recurring: in this renderer a feature exists only where it crosses a surface. Recesses need a raised lip, holes need a genuine gap between parts, and anything pointing outward has to protrude past whatever contains it.

One thing the renderer cannot show: the power button is meant to sit ~1 mm below a bezel ring so a bag cannot press it. A ring is an annulus, and without booleans a solid boss just swallows the button — so it is drawn slightly proud. The recess is a CAD detail, not a modelling one.

CHG

Where the charge port went

Top edge, x 10–19, outboard of the power button. It has been there since it was added — it was just the only top-edge feature drawn correctly, so it was the only one you could see, which made it look like the others were missing rather than it being present.

VERT

Vertical ports — and you were right about the housing

Rotating them is the right call and it generalises, which side-exit never did. Side-exit always pointed at something: the heat spreader on the left, the kickstand on the right, and a bolt-on fan module on either. A vertical axis is clear of all of it by construction rather than by negotiation.

One refinement: both face up, not one up and one down. The top edge is the only one that never rests against a surface, so a downward port would get its cable pinched the moment you set the deck on a desk. And a module clamped to the rail above a port mates straight down onto it, which is the common case.

On the housing — agreed, and it turned out to simplify the rail. The bosses are CF PETG now, part of the printed shell. The aluminium is just the dovetail run between them, which means the rail is a straight extruded section rather than a part that also has to carry four connector bores. Less machining, and the ports become a printed feature you can revise without touching metal.

The collars sit 9 mm below the rear surface. That is not arbitrary: the boss spans 15 mm of y and the rear face rakes across it, so the collar's shallow end is 1.3 mm less deep than its centre — enough to graze the spreader plate at 7.5 mm. The rake catches you constantly on this face.

HINGE

180° — and the culprit is the clamp, not the body

You are right, and the reason is worth knowing because it says what would have to change.

A dense sweep of the wing root against everything it could touch gives two very different numbers:

Wing root enters…at
the clamp's volume178°
the slab body212°

The wing fouls its own mount, not the device. The clamp straddles the hinge axis — x −9.6 to 9.0, with the axis at −6 — so the moment the wing swings past coplanar its root sweeps into the part holding it. The body itself would have allowed 212°.

That matters because it makes the fix cheap and deferrable: a relief radius in the wing root plus a clamp that stops at the axis would recover most of the range, and both are hinge-assembly changes rather than body changes. Nothing about the slab, the rails or the layout is blocking it.

And 180° costs less than it sounds. Past ~193° the wing tips drop below the deck's resting plane, so the band that was ever usable on a desk was 13° wide. What is genuinely lost is the handheld wrap — wings angling down toward the hands — and that was always the weakest justification for a joint already flagged as the highest-risk unsourced part in the build.

Detents are now 175 and 180. Keep the range on the list of things to revisit after a real hinge exists, not before.

SPINE

Decoupling the bottom rail costs 0.7 W

SpineEffective areaTotalFanless
Rear + bottom rail (was)100 cm²318 cm²7.4 W
Rear rail only (now)62 cm²280 cm²6.5 W

Less than it looks, because the bottom rail was already the weakest contributor: it is the foot. Resting on a desk blocks its downward face and most of its convection, so it was only ever supplying about 38 of its 95 cm² in the pose that matters. Decoupling gives up the good-case contribution, not the design case.

What it buys is real: the spine stops being an L across two planes and becomes one 3-axis part, no lapped face has to wrap a corner, and the bottom rail can be a stock Picatinny section at about $15 rather than a custom one at $60.

6.5 W still clears the N100's 6 W base TDP, but margin drops from 20% to 8% — thin enough that the bench-mule measurement stops being a formality. One consequence to carry forward: the strap lugs were integral with the bottom rail for shock load. If that rail becomes a bought section, the lugs need their own load path into the chassis rather than inheriting one.

STACK

Making the connectors visible pushed them through the heatsink

Exactly what you spotted. Bringing the collars out to a realistic 7.5 mm drove them straight through the heat spreader — four intersections — because both features want the same 100 mm of rear real estate either side of the left rail. It was invisible before only because the collars were too small to reach anything.

Fixed by separating them in depth rather than in plan, which costs nothing:

FeatureDepth below the rear surface
Spreader plate0 – 2.5 mm
Fins2.5 – 9.25 mm
Connector collars5 – 15 mm, and outboard of the last fin
Rails0 – 12 mm
Camera pack0 – 18.9 mm

The plate dropped from 3.5 mm to 2.5 mm to make room, which is still plenty of aluminium for spreading — and it gave the fins a millimetre of extra height, so dissipation went up rather than down: 7.1 → 7.2 W. One fin was removed where the collar sweeps through, taking the count to ten.

There is now a permanent rear-collision check, and writing it surfaced something worth knowing: the first two versions of it reported collisions that did not exist. Every rear feature follows the 32 → 18 mm rake, so an axis-aligned bounding box overstates its depth — the plate's box spans 12.5 mm of z purely because it is tilted. The check now measures depth below the local surface instead, where the plate is simply "0 to 2.5 mm" everywhere. That is the right frame for this whole face.

KICK

Kickstand

Mirrored across the centreline into the matching dead zone: x 234–304, y 50–120, hinged along its top edge. It is drawn part-deployed at about 23° so it reads as a leg rather than another blank panel — which is the mistake the vestigial I/O shroud made.

The same conflict applies on that side, and the answer is the same: the right rail's connectors reach x 231, so the stand starts at 234. It also has to clear the right cell blister, which is why it starts at y 50 rather than following the spreader's y 30. A finger notch at the free end gives you somewhere to get a nail under it.

Being on the opposite side to the spreader is not just symmetry — it keeps a fold-out panel off the hot part of the device. A kickstand over the fins would both block them and get warm.

VOID

One bug, four symptoms

The invisible slots, the invisible strap holes and the sunken connectors were all the same mistake, made four times: this renderer has no boolean operations, so anything drawn inside a solid does not exist. A recess has to be faked; a hole has to be a genuine gap between parts.

SymptomCauseFix
Side rails invisibleslots drawn at x 0.4–5.4, entirely inside the shellraised lip + dark face that breaks the surface
Strap lugs have no holebore drawn inside the lugrebuilt as an open bail — four bars round a real void
Connectors sunkencollar 1.5 mm proud of a 12.4 mm body7.5 mm proud, with a visible bore
Rail ends look open2 mm gap between each connector head and the dovetail runrun butts up to the heads

The connector one is worth a note: they were deliberately sunk several revisions ago because they were setting the rear envelope at 20.6 mm. Then they were turned to exit sideways — and the sinking was never undone, even though it no longer bought anything. Protruding in x costs nothing at all.

For the strap lugs, a bore inside a block cannot render no matter how it is coloured, so they are now a genuine bail: a root bar into the body, an outer bar, and two side bars, with an 8 × 16 mm void between them. A 25 mm strap folds through it.

USB

External USB, in the space the cleanup freed

Your instinct about the free space over the battery was right, and it is the best site on the device. Three USB-A ports at x 126–180, y 96–108 — directly above the camera pack, flanked by both back rails.

That position is protected on three sides without adding anything: the rails shield it left and right, the pack shields it from below, and the shroud lip stands 2.6 mm proud around it. A hinge barrel runs along the top of the cluster and a latch catch sits below, so the gasketed cover swings up out of the way. The cover itself is omitted from the model so the ports read.

It also puts the ports where a cable naturally wants to go — down and out past the pack, rather than out of an edge you are holding.

CLEAN

Cleanup pass

Most of your list was right, and two items turned out to be my bugs rather than styling.

  • The mystery ovals and bars — both vestigial, both gone

    The four ovals were an I/O shroud left over from when there was an internal expansion bay, before EXT moved to the rails and power/audio/microSD moved to the top edge. The four bars below them were plastic vent fins from the passive-cooling era, before the aluminium spreader existed — and plastic fins on a plastic wall do essentially nothing anyway. Neither had a job left. Removed.

  • The side rails looked flat because they were not there

    Not a rendering issue: the side-edge M-LOK slots had been deleted by an over-broad edit several revisions back, so those edges were genuinely blank. Restored — three per side. The top-edge ones survived but were cut only 0.3 mm deep, which reads as a decal rather than a slot. All M-LOK slots are now 5 mm pockets, which is what a T-nut actually drops into. They will still read flatter than the back rails, because M-LOK is subtractive by definition — that is the trade that keeps them free in width.

  • TrackPoint was more than twice the size of a real one

    It was a 20 mm dish with an 8.8 mm nub standing 8.5 mm proud — no wonder it read as a rotary encoder. A ThinkPad cap is about 7.5 mm across and stands ~4 mm off the PCB. Now 12 mm dish, 7.5 mm cap.

  • Latches doubled in size

    You are right that they would not have held. They were 16 mm tall and 2.6 mm proud — trim, not a catch. Now 30 mm tall and 12.5 mm proud, with a longer hook that engages further past the seam.

  • Strap lugs now exist, with holes in them

    They were never modelled at all — you were looking at the rubber feet. There are now proper lugs at both bottom outboard corners, integral with the bottom rail so shock load goes into aluminium rather than a printed boss. That is why they head the CNC list.

  • Corners locked at 30%, slider removed

    Done. The parametric control did its job — it settled the M-LOK slot run and caught the panel-clipping limit — and a control that can only produce one right answer is now just a way to break the model.

  • Three material families

    CF PETG is darker, aluminium is much lighter and more specular, and anything bought in — switches, hinges, connectors, the pack, the TrackPoint — is amber. The render should now read as a bill of materials rather than a shape.

CHG

Charging — you found a real gap

There was no USB-C port on the device. The power architecture has assumed one since the ORing scheme was designed — it is the 12.4 V branch, the highest-priority source — but it was never modelled or placed. It is now on the top edge at x 10–19.

On your actual question: no, the camera pack's own USB-C input does not charge the 18650s. It charges the pack. But there is an indirect path, and it is worth knowing because it means you can top the deck up through a battery you already own:

Plug into…Runs the deckCharges 18650sCharges a fitted pack
Deck USB-C PDyesyesyes
A fitted pack's own USB-Cyesyes, indirectlyyes
External NP-F chargernonon/a — charges spares

The indirect path falls out of the staggered setpoints rather than being designed: a fitted pack presents 12.1 V to the rail, that is above the 11.9 V threshold, and the threshold is exactly what enables the 2S charger. So charging the pack in place also trickles the internals. Slow, but free.

Spec the deck port as USB-C PD sink, up to 20 V 3 A. At 60 W it can run the deck at full load and charge both chemistries at once; at 12 V it would be doing well to do one at a time. It is also the only port that needs to survive daily insertion, which is an argument for a board-mounted receptacle with a bolted retention bracket rather than a flying lead.

THERM

Exactly enough aluminium: 24% of the back

You asked for the number and guessed a quarter. It is 24%. A 100 × 95 mm finned plate over the compute board, integral with the left rail, and the fan comes out entirely.

The reason it works at that size is not obvious, and it is the whole answer: fins buy area at roughly a fifth the mass per cm² that flat plate does. Optimal natural-convection fin spacing here — 95 mm fin length, 20 °C above ambient — works out at 7.3 mm, so eleven fins at 7.0 mm pitch is very close to ideal.

OptionAreaFanlessAlu masscm²/g
Full flat back panel, 310 × 130 × 3403 cm²11.5 W326 g1.23
100 × 95 plate + 11 fins325 cm²9.7 W161 g2.02

So: half the mass, 84% of the capability, a quarter of the machined area — and the other three quarters stay printed CF PETG. Your reasoning about weight and cost was right, and the aesthetic you wanted falls straight out of it.

The budget, honestly

SourceEffective area
11 fins, 15 mm proud, both faces230 cm²
Plate face95 cm²
Spine rails — worst case, resting on a desk94 cm²
Total419 cm²

At 11.6 W/m²K (6 convection plus 5.6 radiation from anodised aluminium) and a 45 °C surface — laptop-bottom warm, not a burn — that is 9.7 W dissipated with no fan, measured against the design's 6–8 W PL1 cap. The spine is counted at its desk-blocked value, so the free-standing case has more margin than this.

The fins stop at 9.25 mm proud — below the rails, not above them. I had them at 15 mm on the reasoning that the camera pack sets the envelope at 18.9 mm so there was room. There was room, but that missed something: at 15 mm the fins became the tallest thing on the back after the pack, so setting the deck down on its back would rest it on 2.4 mm fin edges — point loads on the thinnest feature in the build, every single time. Below the rail line, load goes to the rails and the pack instead.

That costs 2.6 W of passive headroom and saves 38 g. The mechanical reason is the one that decides it; the weight is a bonus.

7.1 W passive is not a compromise. The N100's base TDP is 6 W — that is Intel's number for full rated sustained performance, not a throttled state. The 8 W cap in earlier revisions was my headroom, not the chip's requirement. So the shorter fins still cover the processor doing everything it is specified to do, silently.

BOOST

The fan as a module

This is the better half of the idea, and it resolves a tension the design has been carrying since the fan first appeared.

ModehDissipationCovers
Bare — sealed, silent11.67.1 WN100 at its 6 W base TDP, indefinitely
Fan module attached2515.2 Wsustained turbo, converters, a 5G module
Fan module, close-coupled3521.3 Wmore than the deck can draw

A 40 mm USB fan clamped to the left rail, cantilevered over the fin array, blowing into the channels. No new mounting standard — it is the same Picatinny clamp every other module uses, and the rail it wants is the spine, which is already the warm one. Power from EXT 3: a 40 mm fan draws well under the 2.5 W a USB 2.0 port supplies.

Fin geometry is a compromise between the two modes and worth knowing about. Natural convection wants wide spacing so each channel can chimney — the optimum here is 7.3 mm, which is what the 7.0 mm pitch is built around. Forced convection would prefer tighter, taller fins. Since the forced case has better than 2× the margin it needs, the fins are tuned for the passive case and the fan simply overwhelms the difference.

And this is what makes the gasketed caps real. When the fan was internal I wrote that IP67 connectors were pointless because an intake grille meant the device could not be sealed anyway — the caps were only keeping grit out of the contacts.

That is no longer true. With no permanent fan there is no intake, no exhaust, and no moving air path, so the body genuinely can be sealed. The caps are now doing the job they look like they are doing, and your instinct about not killing the waterproofing is exactly why the bolt-on approach is better than a built-in fan — it puts the only opening on a part you can leave at home.

Two things carry over from the earlier active-cooling work and still apply. Rail temperature is a safety limit rather than a comfort one — the rails are the handle, the strap mount and the feet — so keep the thermistor and let it drive throttling instead of a fan curve. And thermal modules still go on the right rail: the left one is now unambiguously a heatsink.

USB

Standard USB ports — and the fan settles it

One correction first: the windows you spotted are on the front top bezel, and they are the WiFi/Bluetooth radio window rather than blank panel. But the idea underneath is right, and the fan is what makes it right.

You cannot have both a fan and an ingress rating. The moment there is an intake grille and an exhaust path, IP67 circular connectors are buying sealing the device as a whole does not have. That was the main argument for M12 and GX12, and it just evaporated.

So EXT 1–3 become USB-A 3.0 panel mounts with gasketed screw caps. What that changes:

M12 / GX12USB-A + cover
Cost, 3 ports≈$60≈$15
Cablescustom pinout, made by youoff the shelf
Sealed when openyes — but so what, there is a fanno
Connector protected in a bagyesyes, by the cap
Lockingscrewfriction

Locking is the one real loss, and it matters less than it looks: following the DFCD pattern, these cables are short jumpers between two things that are both clamped to rails. Nothing hangs off the connector, so the cable is not load-bearing. PWR stays circular though — that is 12 V at several amps into the ORing bus, and a power connector backing out under load is a different class of problem from a data one.

The gasketed cap still earns its place. It is not sealing the device; it is keeping pocket lint and grit out of the contacts of a port that spends its life in a bag.

IO

Power, audio, card — on the top edge

All three go on the top edge, for one reason: it is the only face reachable in every pose. Folded, deployed, tablet, propped — the top edge never gets covered by a wing, blocked by the camera pack, or pressed against a desk. It is also why the encoders and the latch already live there.

FeaturexNote
Power button26–34recessed 1 mm — cannot be pressed in a bag
3.5 mm jack40–476.2 mm barrel, 8 mm deep, fits the 18 mm edge
microSD52–55push-push, card sits flush
M-LOK ×560–252unchanged

Building it caught a bug that had been latent since the top slots were added: the features were centred on MLOK_Z, which is set for the side edges. Those are 18–32 mm thick; the top edge is 18 mm throughout, so the power button was reaching 19.6 mm into an 18 mm edge — it would have poked out the back. The top-edge M-LOK slots had the same fault. Both re-centred, and there is now a check that fails if anything on that edge exceeds its depth.

5G

5G as a module — and one more reason than you gave

Agreed, and the reason you did not list is the strongest one: thermal. A modem adds 0.8 W merely registered and 3.5–5 W transferring — 8% to 50% more heat — inside a sealed, passively cooled slab, with no extra surface area to shed it. That budget is still unmeasured and already the second-highest risk in the build. In a module, it is someone else's air.

The rest lines up too. It frees roughly 1300 mm² of the lower band that was already ~75% packed, and it takes $165 out of a build cost that only gets paid if you ever actually need cellular.

A module is a better antenna site, not a worse one. That is the part worth noticing, because it inverts the usual trade.

This argument was stronger when the body had an aluminium plate: a ground plane confines antennas to one bezel window. With an all-CF-PETG shell there is no plate and the body is largely RF-transparent — only the two 18650s, the camera pack and the metal rails obstruct locally. A module is still cleaner (no cells beside it, free element spacing, no coax through the chassis) but it is no longer the deciding factor. Thermal, volume and cost carry that on their own.

The port layout already handles it, by accident. PWR and EXT 1 sit on the same back rail. USB 3.0 supplies 900 mA at 5 V — 4.5 W — against a modem that peaks at 5 W, which is uncomfortably tight on its own. A module clamped across that rail reaches both connectors: EXT 1 for 10 Gbit/s of data, PWR for 12 V. No new port, no revised pinout.

Two things stay behind. The antenna window keeps existing, just smaller — the X4's WiFi 6 and Bluetooth are onboard, and the rear plate blocks them exactly as thoroughly as it would block cellular, so the band goes from four windows to two at 100 mm spacing for 2×2 MIMO. And the USB hub shrinks rather than disappearing: microSD alone still puts the board one port over, so a small two-port hub shares USB 3.0 #1 between the card reader and the internal bay. Those are never in use at the same time.

Runtime goes back to ≈6.4 h typical on 71.5 Wh — the figure the power section already carries, which accounts for conversion losses — and 5G becomes a runtime cost you opt into on the days you need it.

THUMB

Cutting the rim away from the thumbs

You are right, and the numbers are worse than they look. The thumb caps clear the rim by 2 mm, and the rim is a 9.7 mm wall — so reaching a thumb key means coming over a fence nearly five times taller than the gap you are aiming for.

The rim is cut across the thumb span, x 10–94 of the wing's 161. What makes that safe is worth stating, because the rim is not decoration:

The rim is the bearing surface when the wings fold shut. It sits at z = 0 and lands on the slab's bezel; the keycaps top out 1.2 mm below it and the glass is recessed 1.2 mm below the bezel, so caps clear glass by 2.4 mm. That whole standoff depends on the rim carrying the load.

Cutting a span out does not change the clearance, because the wing is a rigid shell — it still rests on whatever rim remains. What matters is that enough remains, and that it is distributed. After the cut there is 5258 mm² of bearing across all four edges (top 1864, inboard 1354, outboard 1346, bottom 693). Both bottom corners survive, so the wing is still supported at its extremes rather than cantilevered.

A low lip spans the notch instead of nothing at all — 3.7 mm above the well floor, which is 5 mm below the cap tops. Your thumb slides over a rounded edge rather than a wall, and the well stays enclosed against the obvious things.

One honest consequence: with the rim interrupted, the closed device has a ~6 mm slot along the bottom edge of each wing where the lip sits below the bezel. Debris can reach the key well through it. That is the price of the access, and it is the kind of thing the FDM v1 will tell you about faster than any amount of CAD.

SPLAY

Splaying the field inside the housing

Done, at 15°, with the column tops rotated toward the hinge. The housing is untouched — only the board's position within it moves, as you asked.

One construction note that turned out to matter more than the angle. Splaying the main field and the thumb cluster as one block runs out of well at about 13°; splaying the main field alone takes 25°. The 108 × 90 mm block sweeps a bigger circle than the 108 × 68 mm field does, and the well is only 143 × 112. So the thumbs get their own placement and their own shallower angle (5°), which is how ergonomic boards usually do it anyway — and that independence is what buys the splay.

The mirroring is free. A single local rotation produces a correctly mirrored pair, because the left wing is already placed by a mirrored transform. Verified: 15.0° measured off the built geometry, top row 13.2 mm inboard of the bottom, and all 28 caps clear each other by at least 0.3 mm under a separating-axis test.

SWING

220° — but it does the opposite of what you'd expect

The range is extended and the detents are at 175 / 200 / 215. Before you settle on an angle though, here is what opening past coplanar actually does, measured rather than assumed:

HingeKey-plane tiltTip heightOn a desk
175°32°+46 mmclears
180°32°+34 mmclears
190°33°+11 mmjust clears
200°37°−12 mmtips into the desk
210°43°−34 mmtips into the desk
220°50°−53 mmtips into the desk

Opening further makes the keyboard steeper, not flatter, and past about 193° the wing tips go below the deck's resting plane. The hinge axis is vertical and lies in the display plane, so rotating about it wraps the wings forward and down — it cannot change their tilt relative to the desk. The flattest the keyboard ever gets is at 180°, where it is coplanar with the display and therefore shares the deck's 32° rake.

That does not make the request wrong — it makes it mode-specific. Wings wrapping down and inboard is exactly the shape your hands want when you are holding the thing, the way a controller's grips angle away from the body. For handheld and lap use, 200–215° is the right range and that is why the detents are there.

On a desk it is unusable past ~193°, and the answer is one the design already has: take the wings off. Detached, they lie flat at whatever separation and tenting you like, which is strictly better than any hinge angle could manage. Mounted-and-open is the couch pose; detached is the desk pose.

If you want a flatter keyboard while the display stays raked and the wings stay attached, that needs a second hinge axis — a compound joint that swings out and tilts. Two degrees of freedom per wing, on a joint that already has no off-the-shelf answer at one. I would not spend that complexity to duplicate what detaching already does, but the mockup at Phase 0 step 03 is where you would find out.

DOVE

The rail, read off the standard

Third revision of this detail, and this one is measured against MIL-STD-1913 Figure 1 rather than argued from first principles. Your original instinct was right and I talked you out of it.

Figure 1CalloutmmWhere
Head width.835 −.00521.21widest, and the OUTER part
Neck width.617 −.01015.67narrower, toward the mount
Chamfer leg.108, 2× 45°2.74four faces
Groove depth.118 +.0083.00recoil groove
Groove width / pitch.206 / .3945.23 / 10.01unchanged

The head overhangs the neck by 2.77 mm per side, the four 45° faces are the clamping interface, and a jaw hooks under the lower pair. That is exactly "widest at the outside, thinnest toward the device". I had it as a plain wedge because I trusted a search summary over the drawing, and the earlier version before that had it inverted the other way. Both are gone.

Two things surfaced only once the profile was built properly:

  • The standard's dimensions do not close

    .835, .617 and .108 are toleranced independently, so they do not agree: bridging a 15.67 neck to a 21.21 head needs a 2.77 mm leg, against the 2.74 mm the .108 callout gives. Taking .108 literally leaves a 30 micron step in the profile and produces degenerate faces. The leg is now derived from the two widths, which sits inside the .108 tolerance band.

  • Groove depth was 5.6 mm, should be 3.00

    Corrected, and it matters structurally rather than cosmetically: at 3.00 mm the groove floor lands on the head, so the neck and the entire lower undercut stay continuous along the rail. That continuous undercut is what a long clamp actually grips.

The teeth are also no longer chamfered as blocks. The profile is a constant cross-section extruded along the rail, so the 45° faces are the real thing and the longitudinal ends only carry a 0.3 mm edge break instead of the shark-fin taper a uniform inset produced.

WIND

A winding bug that had been there all along

Rebuilding the profile broke every solid in the model — 2,784 non-manifold edges. Chasing it found a defect that predates all of this work.

The lofting primitive emitted its end caps and its side strips consuming shared edges in the same direction, which is non-manifold by construction. It never showed up because orient() flipped faces individually against the mesh centroid, and on simple outlines that happened to land somewhere consistent. It cannot repair a winding conflict between two faces that are both already facing outward — so the moment the rail outline grew past six vertices, it fell apart.

Rather than guess, I enumerated all eight combinations of cap and strip winding and tested each for closure. Exactly two are manifold. The primitives now use one of them, and orient() decides a single global sense for the whole solid by majority vote instead of flipping faces one at a time. Every closed solid in the model now reports zero duplicate edges and zero boundary edges, at every corner setting.

BUG

Transparent battery, missing bezel, flickering ports

Three reports, two root causes, and the first one had been in the model since the shutter rewrite.

  • Mirrored transforms — the battery and the left wing

    Both are placed by transforms whose Jacobian determinant is negative: they mirror the geometry, which reverses face winding. Backface culling then does exactly the wrong thing — it keeps each part's interior and discards its exterior. The battery looked see-through and the left wing lost its rim, from the same cause.

    The fix is general rather than a special case: draw() now measures the handedness of every group's transform at render time and flips the normal test for the mirrored ones. Verified by pixel count — the two wings previously differed wildly and now cover within 2% of each other, and the pack renders solid from the rear.

  • Coincident surfaces — the flickering ports

    Parts here are stacked solids, not booleaned unions, so a feature and its host frequently share an exact face plane. A scan found 54 such pairs at 0.000 mm separation. Two faces at identical depth make the Z-buffer pick per pixel, which is visible as dithering and reads as flicker.

    Two fixes together: a depth bias keyed to build order, scaled by 1/z² so it stays a constant distance in millimetres at any zoom, which breaks every tie the same way — features are built after their hosts, so features win; and separating the worst offenders physically, including the pack's label and vents, which had been straddling the pack's own top face. A dither scan across all five preset views now reports 0.000%.

Both were invisible to the checks I already had. The mesh tests only ever examined geometry in local coordinates, where all of it was correct; the defect lived in the transform. The lesson is the same one the camera bug taught — a check that never crosses a layer boundary cannot see a defect that lives on it.

FACE

Rails on four faces, two standards

Top and bottom are in, and they are deliberately not the same system — because one of them physically cannot be.

FaceThicknessRailWhy
BackPicatinny ×2Hides under the camera pack's 15 mm
Bottom edge32 mmPicatinnyThe only edge wide enough for a 21.2 mm dovetail
Top edge18 mmM-LOK ×518 < 21.2 — a dovetail is wider than the edge
Side edges18–32M-LOK ×3Additive rail would cost 12 mm of width

The top edge runs into exactly the constraint that kept Picatinny off the sides: a 21.2 mm dovetail is wider than the 18 mm edge it would mount to. Carrying one there would mean opening the wedge from 32 → 18 to 32 → 24, which is 6 mm of thickness across the whole top for a rail you would rarely use. M-LOK is free, and an M-LOK antenna mount puts a LoRa whip exactly where it wants to be. If you ever want Picatinny up there, a stock adapter section bolts on.

The bottom rail is the one that costs something: it stands 12.0 mm proud of the bottom edge, taking the device from 130 mm tall to 144 mm. Rubber feet at both bottom corners stand 1.5 mm proud of it, so a bare deck rests on rubber rather than on rail teeth — and with a module fitted, the module becomes the foot.

CLAMP

Release speed and stability

Different answers per face, and the split is the useful part: things you swap often get levers, things you set once get screws.

MountReleaseToolRigidity
Back / bottom Picatinny, throw lever1–2 snoneHigh — the mechanism exists to hold optics under recoil
Side M-LOK, our cam clamp2–3 snoneHigh — T-lugs pull flush into the slot
Top M-LOK, stock T-nut20–30 shex keyHighest — but you are not swapping a LoRa module mid-session

Stability is governed by the moment arm rather than the rail. A module hanging its mass 40 mm off the rail face applies four times the leverage of one hanging it 10 mm out, and that is what a clamp actually has to resist. Practical envelope: engage at least two slots, keep the module under about 300 g, and keep its centre of mass within ~50 mm of the rail face. Inside that a throw-lever mount feels like part of the device; outside it, everything wobbles regardless of how hard you clamp.

One caution specific to printing: a throw-lever clamp works by elastic preload, so it needs a clamp body that does not creep. Printed PETG relaxes under sustained load and a lever tensioned today is looser next month. That is an argument for metal clamps even before it is an argument for metal rails.

CNC

What to send out, when you get there

Your instinct on which parts to machine is right, and the reason is sharper than "metal is stronger". These are the parts where the load runs across print layers rather than along them.

  • Rails — machine them

    A dovetail flank is a thin 45° feature carrying a clamping force that tries to shear it off the rail. In FDM that force lands square across the layer lines, which is the weakest direction in the part; the flank chips and then the clamp never seats the same way twice. Aluminium also makes the 5.23 mm slots dimensionally repeatable, which is what lets a module go back exactly where it was.

  • Strap mounts — machine them first

    If you only send one part out, send this one. A strap anchor sees shock loading rather than static load — the peak when a 1.4 kg deck reaches the end of the strap is several times its weight, and it arrives suddenly. A printed lug that fails there drops the whole device. This is the one part where the failure mode is losing the machine.

  • Handle — machine it

    Same argument as the strap, plus it is the part your hand judges the device by. It is also where a thermal path could usefully run if the passive budget turns out tight.

  • Clamp bodies — machine them too

    Easy to overlook because they are small, but they carry the preload, and preload plus printed plastic equals creep. Machining the rail and then clamping it with a part that relaxes gets you the worst of both.

Everything else — shells, bezels, wing bodies, the camera cradle — stays printed. Those are compression and stiffness parts where CF PETG is genuinely good and where you still want the freedom to iterate. Send out the rails, clamps, strap mounts and handle; keep the geometry that might still change on the printer.

FIT

32 mm, because the hardware did not fit at 28

The volume check finally got done properly, and it failed. The X4's connector stack needs 16 mm of depth, which at a 28 → 18 wedge existed only below y = 25 mm — a band already fully occupied by the two cell blisters and the camera cradle, whose free gaps are 40 mm wide against an 85 mm board.

At 32 → 18 that band grows from 310 × 25 mm to 310 × 55 mm and everything places with real margin: cells +3.4 mm, X4 connector edge +0.8, X4 body +3.5, driver board +3.2. The cost is 4 mm — folded 42 → 46 mm, open 28 → 32 mm.

Two findings came with it. The power stage cannot be one 90 × 45 block — after the X4 and the driver board the leftovers are 33 mm and 38 mm strips, so it has to be two narrow custom PCBs rather than off-the-shelf modules. And the usable band ends up about 75% packed, which is buildable but leaves nothing spare for a part that turns out bigger than its datasheet.

RAIL

Detachable wings — but not on Picatinny

The best part of this idea is that the design already earned it. Because nothing crosses the hinges, each wing is already a self-contained wireless keyboard with its own controller and battery. Detaching one costs exactly nothing functionally — it keeps working. All that was missing was a mount.

Picatinny was the wrong spec for it, though, and the reason is dimensional rather than aesthetic. A MIL-STD-1913 rail is 21.2 mm across the dovetail, and this edge is 18 mm at the top. The rail is physically wider than the thing it would mount to above y = 88, so it would have forced the wedge open to 23 mm and, since the panel needs the full 310 mm of body, added 16 mm of width on top:

SpecSlot / railNatureWidthTop edgeEcosystem
Picatinny MIL-STD-191321.2 mmadditive326 mm23 mmhuge
NATO STANAG 469421.2 mmadditive326 mm23 mmsmall
11 mm dovetail11.0 mmadditive320 mm18 mmsmall
M-LOK7 × 32 mmsubtractive310 mm18 mmhuge

M-LOK is the only one that is subtractive — slots cut into the edge face rather than a rail standing proud of it — so it costs nothing in width and nothing in thickness. Three slots per edge, 7 × 32 mm at the standard 40 mm pitch. The licence is free and open, the hardware ecosystem now rivals Picatinny's, and M-LOK to Picatinny adapter sections are stock parts for about $15 — so if you ever want the Picatinny ecosystem you bolt on a section and have it, without paying 16 mm of width to carry it all the time.

The one trade is that M-LOK is a screw system, not a lever system. For peripherals that is fine — a controller mount is not something you swap mid-session. For the wings, which you will swap, the clamp is your own part anyway: two T-lugs into two slots and a cam lever to tension them. Toolless, repeatable, and exactly as rigid as you make it. The clamp carries the hinge, so the wing still folds normally when mounted.

Three modes, and the third one is the best keyboard the device has.

Mounted — 322 mm folded, wings closed over the glass, as before. Tablet — wings off, a 310 × 130 × 28–18 mm slab at roughly 900 g with a touch panel and a battery that already works as a kickstand. Split — deck propped, wings loose on the desk at whatever separation and angle your shoulders actually want.

That last one is worth calling out: the hinge fixes the two halves in a rigid relationship, which is the one thing a split keyboard exists to avoid. Taking them off removes the constraint entirely — unlimited separation, independent tenting, arms wherever you like. The mounted mode is for carrying and for the couch; the detached mode is for actually working.

The clamp costs 6 mm outboard of each edge, so the wings grow from 155 to 161 mm to still meet at the seam — which is a gain, not a cost: the key budget goes from 9 mm of slack to 15 mm. Overall footprint 322 mm folded, 643 mm deployed.

FIX

Pogo, corners, and the crooked vents

Pogo pins moved to the top bezel. Your reasoning holds on both counts — the bottom bezel is exactly where palms rest, and the open band above the key field is where each wing's controller naturally sits, so the run from pad to charger is short. The pads moved to the top rim to match; verified aligned to 0.1 mm on both sides, which matters because the right wing mirrors and it is easy to get the pairs crossed.

Corners locked at 50% — that is now the default the model opens at. On the slab that is a 4 mm cut at the bottom corners and 9.5 mm at the top; on the wings 5 / 18 / 11 / 4. The slider stays, because it is still the fastest way to sanity-check a change. One consequence worth knowing: at full cut the top and bottom M-LOK slots run off the corner flats, since three slots at the standard 40 mm pitch need 112 mm of straight edge and full cut leaves 103 mm. At 50% there are 116 mm. Another small vote for 50%.

The vents were mine. I had raked them 8 mm across their length to run parallel to the wedge, which in practice read as crooked rather than deliberate, and the skew made adjacent fins appear to interleave. They are now straight, evenly pitched at 6.5 mm, and given a proper margin from the I/O shroud.

One more bug fell out of building the slots: the loft bounds were passed the wrong way round for the left edge, which sends the two chamfer rings through each other and tears the solid open — 96 defective edges. Rather than fix the call site, the plate primitive now checks and swaps, so the whole class is gone.

LATCH

Flip latches, and the corners

Magnets are gone. Two over-centre flip latches now straddle the centre seam on the back face — the surface that faces outward when the device is shut. The lever body and hook are carried on the left wing, the keepers on the right, so throwing them clamps the two wing tips together. That locks the whole assembly, because a wing can only open by swinging its tip forward and outward, and neither tip can move while they are pinned to each other.

They sit mid-height rather than near the tips, which is deliberate: both tip corners carry flats, and anything parked there stops being on the wing as soon as you take the corners back. Mid-height is the one band on the outboard edge with no corner cut at any setting.

You overrode my earlier objection to draw latches and that is your call — but the objection was about protrusion, so here is the number rather than the argument. Surface-mounted, they stand 5.1 mm proud of the back face, taking the closed device from 42 mm to about 47 mm over the latch footprint. Sinking them flush needs a pocket cut into the shell, which this renderer cannot do without booleans; real CAD can, and it would buy most of that 5 mm back.

The corner cuts are now a live control, starting square. The profile opens as a plain rectangle and the slider takes the flats back to full depth, so you can decide what to remove by looking at it rather than by me choosing for you.

Two things came out of building it. The corner magnets you spotted were genuinely floating — sited at the wing tip, they hung in mid-air the moment the flats were cut. Both are gone with the magnets, but the failure was mine and my orphan check was too coarse to see it: it compared bounding boxes, which cannot tell that a feature has drifted off a chamfer. There is now a containment test that checks every feature's footprint against the actual host outline, run at square, half and full cut. It immediately found the hinge barrels hanging 15 mm off the corners at full cut — same bug, different part — and they have been moved into the band where the vertical edge still exists.

And it found the real limit on the slab: 19 mm. A corner cut runs diagonally across the bezel, and with 9 mm of side bezel and 10.25 mm of top bezel, anything deeper crosses into the panel's active area — the 28 mm cut I had been drawing was clipping the glass by 4 mm. That is the "without damaging functionality" line you asked for, and it is a hard geometric one: to cut deeper the body has to grow, because the panel will not shrink.

The wings have no such ceiling. Their rim is derived from the outline so it follows any cut automatically, and no key, pointer or latch sits within reach of a corner — which is why the wing can carry a 36 mm flat at the palm corner while the slab cannot.

NAV

Panning — and what it uncovered

Shift-drag or right-drag pans; plain drag still orbits and the wheel still zooms. Shift plus the arrow keys pans from the keyboard. Panning moves the orbit target along the camera's own right and up axes, so it tracks whatever you are looking at rather than sliding along world axes — and it scales with zoom, so a drag covers the same amount of screen whether you are framing the whole device or one keycap. Any view preset recentres.

Adding it exposed a bug that had been there since the shutter rewrite: the model was rendering upside down and back-to-front.

Panning needs the camera's right and up vectors, and the first thing my test did was check that panning "up" moves the view up. It moved it down. Following that back found two independent sign errors that had been quietly cancelling each other out.

The camera's right vector was negated. Because up is derived from it, that flipped too, rolling the entire image 180°. Separately, the transform that rakes the deck back was negating the screen's own normal, laying the plank face down. Together: a face-down device viewed through a 180°-rolled camera reads as an upright device seen from behind — plausible enough to survive several rounds of review, mine included. Verified now by projecting known points: the top edge lands above the bottom edge, the right side lands right of the left, and the display's normal points at the camera.

Worth saying because it is the honest lesson from this pass: my earlier checks all tested the mesh, and the mesh was fine. Nothing tested the camera. A defect one layer outside where you are looking is invisible no matter how thoroughly you check the layer you are in.

THK

How thick this actually gets

You asked for real numbers, so I built the stack-up rather than guessing — and it turned up a constraint worth knowing about before any CAD happens.

Slab, thick endmmWingmm
Bezel / front wall1.5Rim above the caps1.2
Cover glass + OCA touch1.1Keycap3.0
LCD module + backlight3.5Choc switch above PCB5.5
Panel frame + air1.5PCB1.6
Radxa X4 + port stack16.0Floor2.0
CF PETG rear wall3.0Clearance0.7
Clearance1.9
Slab total28.0Wing total14.0

One number sets the whole device: the Radxa X4's connectors are 16 mm tall. Stacked USB-A is 15.6 mm and the RJ45 is 13.5 mm — the board itself is only 1.6 mm. That single stack is why the slab's thick end is 28 mm rather than about 20 mm.

Rather than desoldering them, point them inward and let them be the expansion bay. Everything you wanted to add — KVM, LoRa, LTE, SDR — is a USB device, so the X4's own ports become the bay's connectors at zero cost and zero rework. External I/O is then a low-profile USB-C board on the top edge, which needs about 6 mm. Desoldering would buy roughly 8 mm of thickness but it is irreversible and puts the board at risk.

Measured whereFoldedOpen
Top edge3218
Bottom edge4228
Over the cell blisters45.531.5
Over the camera pack6147

Opening it makes it thinner, not thicker. The wings stop being a layer stacked on the display and become coplanar with it, so 42 mm folded becomes 28 mm open. That is the opposite of a clamshell and worth designing toward — the deployed device is a 28 mm raked plank, and only the camera pack breaks that.

The 61 mm at the pack is the honest cost of a 39 mm camera battery on a 28 mm deck, and it is local: it applies over one 70 × 60 mm patch at the lower rear, not across the device. Pull the pack and you are back to 42 mm folded on internal cells.

For scale: a GPD Pocket 4 is 22 mm, a uConsole 34 mm, an MNT Pocket Reform 45 mm. At 42 mm folded this sits between the last two, which is about right for something carrying a 12.3" panel, an x86 board, two 18650s and a full keyboard.

Why there is now one camera bay, not two

Doing the stack-up surfaced a fit problem. Only the thick lower band has usable depth, and everything tall wants to live there at once: the X4 at 16 mm, the cells at 19 mm, the camera pocket at 18 mm, the panel driver board at 10 mm, plus the power stage. Two bays did not fit.

Dropping to one is the right cut rather than a compromise, because the internal cells already did the second bay's job. Its only remaining purpose was range, and a bag of spares serves that better than 300 g of permanently carried battery. Removing it frees about 4,700 mm² in the one band where space is actually contested, and it centres the pack — which is where you want that mass anyway.

PTR

TrackPoint or Pimoroni

Both work. The TrackPoint is the better mechanical fit and I've modelled it, outboard of the key field on the right wing as you asked.

Mechanically the TrackPoint wins on the rule above. A low-profile cap in a shallow dish clears the rim easily. The Pimoroni's ball has to be sunk deep enough that its crown stays below the rim, which both makes it awkward to reach and defeats the point of a ball. If you want the Pimoroni, put it on the slab — in the bottom bezel beside the display, where nothing folds over it — rather than on a wing.

Software is the other way round. The Pimoroni is I²C and undramatic. TrackPoint support in ZMK is out of tree: the mainline PR was never merged, so you'd run infused-kim/kb_zmk_ps2_mouse_trackpoint_driver as a module, bit-banging PS/2 on the nRF52840. It's well-travelled and people ship it, but you're pinned to a third-party module across ZMK updates, and you'll need to identify the pins on the harvested module yourself.

On the split question you raised — you're right to think about it, and there's a way to make it stop mattering. Pointing devices are simplest on the central half, so make the right wing the central and the left the peripheral. Nothing about ZMK requires the left half to be central; it's just convention. The pointer then sits on the central half exactly where you want it, and the constraint evaporates.

One ergonomic note, then it's your call: right of all keys puts the nub under the ring or little finger, which is weak for a force-sensing stick — the conventional spot is mid-field between the index columns. If it turns out to fight you, that's a wing respin, so it's worth resolving during the layout shakedown on an off-the-shelf split rather than after PCBs.

NOTE

What this model is not

A massing study: proportions, controls and a finish direction. Not manufacturing geometry — no nozzle-sized radii, wall thicknesses, bosses, fasteners or authoritative internal interference analysis. The official X4 assembly has now proven that this 32→18 mm baseline is too thin.

The separate CadQuery study under cad/ owns the provisional internal packaging candidate. It imports vendor geometry, draws the cells and aluminum rail frame, and checks reserved volumes. This viewer stays on the old envelope until a dimensioned touch kit replaces the provisional display reserve.