Read this model as text
A MagSafe card wallet that prints as one flat sheet, a few layers high, and folds into shape like a paper kit. It has a pocket for cards, a second pocket for folded bank notes, a seat for a stick-on MagSafe magnet ring, and an outer flap that pops into a triangle so the wallet doubles as a phone stand. No glue, no loose parts, every function comes from a fold.
The image shows the solid OpenSCAD renders at cards 4 · cash_room 1 · magnet_diameter 56 · panel_thickness 0.6 · fold_thickness 0.4 · card_play 1 · fold 0 · stand 0 · color_wallet SteelBlue.
Origami MagSafe wallet and phone stand, folded from one flat print
mick/origami-magsafe-wallet@0.1.0
Report
For a legal or policy problem: a license violation, personal data, somebody else’s work republished as their own. A model that prints badly is a comment, not a report.
Parameters
from sourceDescription
What is this
A MagSafe card wallet that prints as one flat sheet, a few layers high, and folds into shape like a paper kit. It has a pocket for cards, a second pocket for folded bank notes, a seat for a stick-on MagSafe magnet ring, and an outer flap that pops into a triangle so the wallet doubles as a phone stand. No glue, no loose parts, every function comes from a fold.
What you use it for
Carrying three to five cards and a few notes on the back of a MagSafe phone, and propping the phone up on a desk. Sized to print in one piece on a 180 mm bed (Bambu A1 mini). Print flat with fold = 0. Then fold, always toward the top of the print: the divider up onto the front panel, the front panel over the back, the side flap over the front with both arrow tabs pushed through their slits (one barb first, like a button), and last the stand flap around the bottom with its hook tucked into the top slit. Stick the magnet ring into the shallow groove on the outside of the back panel. For the stand, pull the hook out and tuck it into one of the two lower slits.
Design notes
The bed side becomes the outside, so the wallet shows the plate texture all round and the thin fold layers sit on the outer surface. Folds are bands as wide as what they wrap, not sharp creases, so they bend in a gentle curve.
The back panel faces the phone. A groove one layer deep on its bed side centres the magnet ring, and a slot inside the ring lets your thumb slide the cards up, so no ejector is needed. The front panel hangs on one long side of the back and is locked on the other side by a flap with two barbed tabs. The divider hangs on the bottom of the front panel and folds up inside: cards sit between back and divider, notes folded in thirds between divider and front, both open at the top. Its fold is the floor of the note pocket.
The stand flap hangs on the bottom of the back panel and wraps around the bottom of the whole stack, which closes the card pocket. It has one wide crease in the middle and ends in a hook that is folded back, so it enters a slit pointing down, the same way cards go in. Top slit is closed, the two lower slits give a triangle. Under load the legs want to spread and the hook pulls against the upper edge of its slit, which is what keeps the triangle up. Ribs on the legs stiffen them and hide in the gap the side flap leaves between stand flap and front panel. The crease and the hook bend every day, so they are a single layer and wide. Expect roughly 40 degrees of screen angle upright and a steep 75 to 80 degrees in landscape, where the phone leans on the end of the triangle. The flap length is what the 180 mm bed allows.
Print tips: PETG, 0.2 mm layers, so panels are three layers and folds are two. Set the bottom and top infill pattern to lines at 45 degrees so the lines cross every fold, never run along it. The preview at fold above 0 uses stiff bands with square corners, the real bands curve.
Parameters
cards and cash_room set how thick the two pockets are, and with that the width of every fold band. magnet_diameter is the outer diameter of your stick-on ring, the groove assumes a ring 5 mm wide. panel_thickness and fold_thickness are the two heights in the sheet, keep them multiples of your layer height. card_play is the room around a card. fold and stand are preview only: fold 0 is what you print and 100 shows it folded, stand pops the flap into its triangle once fold is 100 and shows the phone. color_wallet is the display colour.
Use with your agent
{
"mcpServers": {
"remixcad": {
"type": "http",
"url": "https://remix-cad.vercel.app/api/mcp"
}
}
}get_model("mick/origami-magsafe-wallet@0.1.0")Returns the manifest, the source, the import closure and the license obligations. Full MCP setup.
Parameter table
Parsed from the Customizer annotations in main.scad| Name | Default | Range | Unit | Description |
|---|---|---|---|---|
| cards | 4 | 2 to 5 step 1 | ||
| cash_room | 1 | 0 to 2 step 0.5 | ||
| magnet_diameter | 56 | 50 to 60 step 0.5 | ||
| panel_thickness | 0.6 | 0.4 to 1 step 0.1 | ||
| fold_thickness | 0.4 | 0.2 to 0.6 step 0.02 | ||
| card_play | 1 | 0.5 to 2 step 0.25 | ||
| fold | 0 | 0 to 100 step 5 | ||
| stand | 0 | 0 to 100 step 10 | ||
| color_wallet | "SteelBlue" | SteelBlue, Silver, Gainsboro, White, DimGray, Black, SlateGray, FireBrick, ForestGreen, Goldenrod |
Lineage
0 models depend on this oneOnly what this model came from and what came from it.
License
Whoever downloads this takes these obligations along- mick/origami-magsafe-wallet@0.1.0 is MIT
Source
main.scad is the entrypointmain.scad
// A MagSafe card wallet printed as one flat sheet a few layers high and folded like a
// paper kit: a card pocket, a note pocket, a seat for a magnet ring and an outer flap
// that pops into a triangle as a phone stand. Every fold goes toward the top of the
// print, so the bed side becomes the outside. No glue, no loose parts.
/* [Wallet] */
// Number of cards it should hold.
cards = 4; // [2:1:5]
// Room for folded bank notes, in mm.
cash_room = 1; // [0:0.5:2]
// Outer diameter of the stick-on MagSafe ring.
magnet_diameter = 56; // [50:0.5:60]
/* [Print] */
// Thickness of the panels. Three layers of 0.2.
panel_thickness = 0.6; // [0.4:0.1:1]
// Thickness of the fold lines. Two layers of 0.2.
fold_thickness = 0.4; // [0.2:0.02:0.6]
// Room around a card, per side.
card_play = 1; // [0.5:0.25:2]
/* [Preview] */
// 0 is the flat sheet you print. 100 shows it folded.
fold = 0; // [0:5:100]
// Pops the flap into a phone stand. Works when fold is 100.
stand = 0; // [0:10:100]
/* [Colour] */
// Display only, the STL carries no colour.
color_wallet = "SteelBlue"; // [SteelBlue, Silver, Gainsboro, White, DimGray, Black, SlateGray, FireBrick, ForestGreen, Goldenrod]
/* [Hidden] */
$fn = 64;
card_long = 85.6;
card_short = 54;
card_t = 0.76;
bed = 174; // what we allow ourselves of a 180 mm bed
t = panel_thickness;
ft = min(fold_thickness, t);
flex = min(0.2, ft); // folds that bend every day: one layer
W = max(card_short + 2 * card_play, magnet_diameter + 2); // back panel, upright
H = card_long + 1;
Wc = W - 1.5; // front panel, clear of the side fold
inner = cards * card_t + cash_room + 2 * t; // cards, divider, notes, tab heads
s_bc = inner + 2 * t; // fold between back and front
s_left = s_bc + t; // side flap, around the front panel as well
s_bot = s_bc + 2 * t + 0.3; // stand flap, around the side flap too
s_cd = cash_room + 3 * t; // fold between front and divider, around the notes
divider_h = 55;
r = 3; // corner radius of the panels
edge = r + 1; // folds stop this far from a corner
flap_w = 10;
neck_w = 12;
neck_l = 2.5;
head_l = 7;
barb = 2;
tip_w = 4;
slit = t + 0.6;
// Stand flap: leg, crease, leg, hook band, hook.
crease_w = 8;
hook_band = 4;
hook_l = 9;
hook_w = 16;
hook_slit = t + 0.8;
flap_len = min(68, bed - H - s_bot - hook_band - hook_l);
leg = (flap_len - crease_w) / 2;
leg_half_w = 26;
y_closed = flap_len + hook_band / 2; // slit heights on the front panel
y_stand = [0.58 * flap_len, 0.72 * flap_len];
// Magnet ring, high on the back so the wallet hangs low on the phone.
ring_w = 5;
ring_cy = H - magnet_diameter / 2 - 2.5;
// Triangle of the stand, for the preview.
l1 = leg + crease_w / 2;
l2 = leg + crease_w / 2 + hook_band / 2;
base = y_stand[0];
alpha = acos((l1 * l1 + base * base - l2 * l2) / (2 * l1 * base));
beta = acos((l2 * l2 + base * base - l1 * l1) / (2 * l2 * base));
f = fold / 100;
k = fold >= 100 ? stand / 100 : 0;
A = 90 * f; // each fold band turns 90 degrees at both of its edges
D = 20 * f; // tabs dive through their slit
hook_turn = (165 + (10 - beta) * k) * f;
xc0 = W / 2 + s_bc; // where the front panel starts in the flat sheet
echo(str("Flat sheet: ", W + s_left + flap_w + neck_l + head_l + s_bc + Wc, " x ",
H + s_bot + flap_len + hook_band + hook_l, " mm"));
// ---- 2D helpers ----
module rounded(rad) { offset(r = rad) offset(delta = -rad) children(); }
// A slot with round ends, long side along x.
module slot(l, w) {
hull() for (s = [-1, 1]) translate([s * (l - w) / 2, 0]) circle(d = w);
}
// ---- Back panel: phone side ----
module back3d() {
difference() {
linear_extrude(height = t)
difference() {
rounded(r) translate([-W / 2, 0]) square([W, H]);
// thumb slot inside the ring, to slide the cards up
translate([0, ring_cy]) rotate(90) slot(36, 16);
}
// groove one layer deep on the bed side that centres the magnet ring
translate([0, ring_cy, -0.01])
linear_extrude(height = 0.21)
difference() {
circle(d = magnet_diameter + 0.6);
circle(d = magnet_diameter - 2 * ring_w - 0.6);
}
}
}
// ---- Front panel and divider, to the right of the back in the flat sheet ----
// A point that ends up at folded x sits at xc0 + W/2 - x in the sheet.
module front2d() {
difference() {
rounded(r) translate([xc0, 1]) square([Wc, H - 3]);
// notch in the top edge to pinch notes and cards
translate([xc0 + W / 2, H + 1]) circle(r = 10);
// slits for the two barbed tabs of the side flap
for (y = tab_y())
translate([xc0 + W - flap_w - 0.2 - slit / 2, y]) rotate(90) slot(neck_w + 1.5, slit);
// slits for the hook of the stand flap: closed, and two stand positions
for (y = concat([y_closed], y_stand))
translate([xc0 + W / 2, y]) slot(hook_w + 1, hook_slit);
}
}
module band_bc2d() { translate([W / 2 - 0.05, edge + 1]) square([s_bc + 0.1, H - 3 - 2 * edge]); }
module band_cd2d() { translate([xc0 + edge, 1 - s_cd - 0.05]) square([Wc - 2 * edge, s_cd + 0.1]); }
module divider2d() {
difference() {
rounded(r) translate([xc0 + 1, 1 - s_cd - divider_h]) square([Wc - 2, divider_h]);
// scoop in what becomes the top edge of the divider
translate([xc0 + W / 2, 1 - s_cd - divider_h - 3]) circle(r = 10);
}
}
// ---- Side flap, drawn on the right and mirrored to the left ----
function tab_y() = [0.26 * H, 0.74 * H];
module band_side2d() { translate([W / 2 - 0.05, edge]) square([s_left + 0.1, H - 2 * edge]); }
module flap2d() {
x0 = W / 2 + s_left;
hull() {
translate([x0 - 0.01, edge]) square([0.02, H - 2 * edge]);
for (y = [edge + 6, H - edge - 6]) translate([x0 + flap_w - 2, y]) circle(r = 2);
}
}
module tab2d(yc) {
x1 = W / 2 + s_left + flap_w;
hw = neck_w + 2 * barb;
translate([x1 - 0.01, yc - neck_w / 2]) square([neck_l + 1, neck_w]);
hull() {
for (s = [-1, 1]) translate([x1 + neck_l + 0.75, yc + s * (hw / 2 - 0.75)]) circle(d = 1.5);
translate([x1 + neck_l + head_l - tip_w / 2, yc]) circle(d = tip_w);
}
}
// ---- Stand flap, below the back panel ----
module band_bot2d() { translate([-(W / 2 - edge), -s_bot - 0.05]) square([W - 2 * edge, s_bot + 0.1]); }
// One leg between y0 and y0 + len, with two ribs on the print top.
module leg3d(y0, len) {
linear_extrude(height = t) rounded(2) translate([-leg_half_w, y0]) square([2 * leg_half_w, len]);
for (x = [-12, 12]) translate([x - 0.8, y0 + 2, t - 0.01]) cube([1.6, len - 4, t]);
}
module strip2d(half_w, y0, len) { translate([-half_w, y0 - 0.05]) square([2 * half_w, len + 0.1]); }
module hook2d(y_top) {
hull() {
translate([-hook_w / 2, y_top - 0.02]) square([hook_w, 0.02]);
for (s = [-1, 1]) translate([s * (hook_w / 2 - 3), y_top - hook_l + 3]) circle(r = 3);
}
}
// ---- Folding ----
module ext(h) { linear_extrude(height = h) children(); }
// Turn the children around a fold line on the bed: along x at height y, or along y at x.
module hinge_x(y, a) { translate([0, y, 0]) rotate(a = a, v = [1, 0, 0]) translate([0, -y, 0]) children(); }
module hinge_y(x, a) { translate([x, 0, 0]) rotate(a = a, v = [0, 1, 0]) translate([-x, 0, 0]) children(); }
module front_chain() {
hinge_y(W / 2, -A) {
ext(ft) band_bc2d();
hinge_y(xc0, -A) {
ext(t) front2d();
hinge_x(1, -A) {
ext(ft) band_cd2d();
hinge_x(1 - s_cd, -A) ext(t) divider2d();
}
}
}
}
module side_chain() {
hinge_y(W / 2, -A) {
ext(ft) band_side2d();
hinge_y(W / 2 + s_left, -A) {
ext(t) flap2d();
for (y = tab_y()) hinge_y(W / 2 + s_left + flap_w, -D) ext(t) tab2d(y);
}
}
}
module stand_chain() {
y1 = -s_bot; // start of the first leg
y2 = y1 - leg; // start of the crease
y3 = y2 - crease_w; // start of the second leg
y4 = y1 - flap_len; // start of the hook band
y5 = y4 - hook_band; // start of the hook
turn = (alpha + beta) * k / 2;
hinge_x(0, -A) {
ext(ft) band_bot2d();
hinge_x(y1, -(A - alpha * k)) {
leg3d(y2, leg);
hinge_x(y2, -turn) {
ext(flex) strip2d(22, y3, crease_w);
hinge_x(y3, -turn) {
leg3d(y4, leg);
hinge_x(y4, -hook_turn / 2) {
ext(flex) strip2d(hook_w / 2, y5, hook_band);
hinge_x(y5, -hook_turn / 2) ext(t) hook2d(y5);
}
}
}
}
}
}
module wallet() {
back3d();
front_chain();
mirror([1, 0, 0]) side_chain();
stand_chain();
}
color(color_wallet) wallet();
// Preview only: the magnet ring once folded, the phone once the stand is out.
if (fold > 0)
color("Goldenrod") translate([0, ring_cy, -0.8])
linear_extrude(height = 1) difference() {
circle(d = magnet_diameter);
circle(d = magnet_diameter - 2 * ring_w);
}
if (k > 0)
color("DimGray") translate([-35.5, ring_cy - 80, -8.8])
linear_extrude(height = 8) rounded(8) square([71, 147]);
Comments
Context, not a score. Comments never move a model up or down the results.No comments yet
Printed it? A note about your material and the clearance you landed on saves the next person a failed print.
